1 /* Type handling functions.
2 Copyright (C) 2019-2020 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_file_t
*fp
, ctf_id_t id
)
29 return (LCTF_TYPE_ISPARENT (fp
, id
));
33 ctf_type_ischild (ctf_file_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_file_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_file_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
113 const char **name
, ctf_id_t
*membtype
)
115 ctf_file_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_file_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
232 ctf_file_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_file_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
285 ctf_file_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 container.
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_file_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 container, 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_file_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 container, 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_file_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 container, in arbitrary order.
490 We pass the name of each variable to the specified callback function. */
493 ctf_variable_iter (ctf_file_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 container, 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_file_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. */
589 ctf_type_resolve (ctf_file_t
*fp
, ctf_id_t type
)
591 ctf_id_t prev
= type
, otype
= type
;
592 ctf_file_t
*ofp
= fp
;
593 const ctf_type_t
*tp
;
596 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
598 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
600 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
606 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
607 || tp
->ctt_type
== prev
)
609 ctf_dprintf ("type %ld cycle detected\n", otype
);
610 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
619 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
622 return CTF_ERR
; /* errno is set for us. */
625 /* Like ctf_type_resolve(), but traverse down through slices to their contained
629 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
631 const ctf_type_t
*tp
;
633 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
636 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
637 return CTF_ERR
; /* errno is set for us. */
639 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
640 return ctf_type_reference (fp
, type
);
644 /* Look up a name in the given name table, in the appropriate hash given the
645 kind of the identifier. The name is a raw, undecorated identifier. */
647 ctf_id_t
ctf_lookup_by_rawname (ctf_file_t
*fp
, int kind
, const char *name
)
649 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
652 /* Look up a name in the given name table, in the appropriate hash given the
653 readability state of the dictionary. The name is a raw, undecorated
656 ctf_id_t
ctf_lookup_by_rawhash (ctf_file_t
*fp
, ctf_names_t
*np
, const char *name
)
660 if (fp
->ctf_flags
& LCTF_RDWR
)
661 id
= (ctf_id_t
) ctf_dynhash_lookup (np
->ctn_writable
, name
);
663 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
667 /* Lookup the given type ID and return its name as a new dynamically-allocated
671 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
674 ctf_decl_node_t
*cdp
;
675 ctf_decl_prec_t prec
, lp
, rp
;
680 if (fp
== NULL
&& type
== CTF_ERR
)
681 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
684 ctf_decl_push (&cd
, fp
, type
);
689 ctf_set_errno (fp
, cd
.cd_err
);
693 /* If the type graph's order conflicts with lexical precedence order
694 for pointers or arrays, then we need to surround the declarations at
695 the corresponding lexical precedence with parentheses. This can
696 result in either a parenthesized pointer (*) as in int (*)() or
697 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
699 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
700 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
702 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
703 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
705 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
707 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
709 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
710 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
712 ctf_file_t
*rfp
= fp
;
713 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
714 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
716 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
717 ctf_decl_sprintf (&cd
, " ");
721 ctf_decl_sprintf (&cd
, "(");
725 switch (cdp
->cd_kind
)
730 /* Integers, floats, and typedefs must always be named types. */
734 ctf_set_errno (fp
, ECTF_CORRUPT
);
739 ctf_decl_sprintf (&cd
, "%s", name
);
742 ctf_decl_sprintf (&cd
, "*");
745 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
751 ctf_id_t
*argv
= NULL
;
753 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
754 goto err
; /* errno is set for us. */
756 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
758 ctf_set_errno (rfp
, errno
);
762 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
763 fi
.ctc_argc
, argv
) < 0)
764 goto err
; /* errno is set for us. */
766 ctf_decl_sprintf (&cd
, "(*) (");
767 for (i
= 0; i
< fi
.ctc_argc
; i
++)
769 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
772 goto err
; /* errno is set for us. */
773 ctf_decl_sprintf (&cd
, "%s", arg
);
776 if ((i
< fi
.ctc_argc
- 1)
777 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
778 ctf_decl_sprintf (&cd
, ", ");
781 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
782 ctf_decl_sprintf (&cd
, "...");
783 ctf_decl_sprintf (&cd
, ")");
796 ctf_decl_sprintf (&cd
, "struct %s", name
);
799 ctf_decl_sprintf (&cd
, "union %s", name
);
802 ctf_decl_sprintf (&cd
, "enum %s", name
);
805 ctf_decl_sprintf (&cd
, "volatile");
808 ctf_decl_sprintf (&cd
, "const");
811 ctf_decl_sprintf (&cd
, "restrict");
814 /* No representation: just changes encoding of contained type,
815 which is not in any case printed. Skip it. */
823 ctf_decl_sprintf (&cd
, ")");
827 (void) ctf_set_errno (fp
, ENOMEM
);
829 buf
= ctf_decl_buf (&cd
);
835 /* Lookup the given type ID and print a string name for it into buf. Return
836 the actual number of bytes (not including \0) needed to format the name. */
839 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
841 char *str
= ctf_type_aname (fp
, type
);
845 return CTF_ERR
; /* errno is set for us. */
848 snprintf (buf
, len
, "%s", str
);
852 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
857 /* Lookup the given type ID and print a string name for it into buf. If buf
858 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
861 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
863 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
864 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
867 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
868 The name will live as long as its ctf_file_t does. */
871 ctf_type_name_raw (ctf_file_t
*fp
, ctf_id_t type
)
873 const ctf_type_t
*tp
;
875 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
876 return NULL
; /* errno is set for us. */
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_file_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_file_t
*fp
, ctf_id_t type
)
901 const ctf_type_t
*tp
;
905 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
906 return -1; /* errno is set for us. */
908 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
909 return -1; /* errno is set for us. */
911 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
914 return fp
->ctf_dmodel
->ctd_pointer
;
917 return 0; /* Function size is only known by symtab. */
920 return fp
->ctf_dmodel
->ctd_int
;
923 /* ctf_add_array() does not directly encode the element size, but
924 requires the user to multiply to determine the element size.
926 If ctf_get_ctt_size() returns nonzero, then use the recorded
929 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
932 if (ctf_array_info (fp
, type
, &ar
) < 0
933 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
934 return -1; /* errno is set for us. */
936 return size
* ar
.ctr_nelems
;
938 default: /* including slices of enums, etc */
939 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
943 /* Resolve the type down to a base type node, and then return the alignment
944 needed for the type storage in bytes.
946 XXX may need arch-dependent attention. */
949 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
951 const ctf_type_t
*tp
;
952 ctf_file_t
*ofp
= fp
;
955 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
956 return -1; /* errno is set for us. */
958 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
959 return -1; /* errno is set for us. */
961 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
966 return fp
->ctf_dmodel
->ctd_pointer
;
971 if (ctf_array_info (fp
, type
, &r
) < 0)
972 return -1; /* errno is set for us. */
973 return (ctf_type_align (fp
, r
.ctr_contents
));
982 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
984 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
985 ssize_t size
, increment
;
988 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
989 vmp
= (unsigned char *) tp
+ increment
;
991 if (kind
== CTF_K_STRUCT
)
992 n
= MIN (n
, 1); /* Only use first member for structs. */
994 if (size
< CTF_LSTRUCT_THRESH
)
996 const ctf_member_t
*mp
= vmp
;
997 for (; n
!= 0; n
--, mp
++)
999 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
1000 align
= MAX (align
, (size_t) am
);
1005 const ctf_lmember_t
*lmp
= vmp
;
1006 for (; n
!= 0; n
--, lmp
++)
1008 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
1009 align
= MAX (align
, (size_t) am
);
1017 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1018 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1020 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
1021 align
= MAX (align
, (size_t) am
);
1022 if (kind
== CTF_K_STRUCT
)
1031 return fp
->ctf_dmodel
->ctd_int
;
1033 default: /* including slices of enums, etc */
1034 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1038 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1041 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
1043 const ctf_type_t
*tp
;
1045 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1046 return -1; /* errno is set for us. */
1048 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1051 /* Return the kind (CTF_K_* constant) for the specified type ID.
1052 Slices are considered to be of the same kind as the type sliced. */
1055 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
1059 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1062 if (kind
== CTF_K_SLICE
)
1064 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1066 kind
= ctf_type_kind_unsliced (fp
, type
);
1072 /* Return the kind of this type, except, for forwards, return the kind of thing
1073 this is a forward to. */
1075 ctf_type_kind_forwarded (ctf_file_t
*fp
, ctf_id_t type
)
1078 const ctf_type_t
*tp
;
1080 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1081 return -1; /* errno is set for us. */
1083 if (kind
!= CTF_K_FORWARD
)
1086 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1087 return -1; /* errno is set for us. */
1089 return tp
->ctt_type
;
1092 /* If the type is one that directly references another type (such as POINTER),
1093 then return the ID of the type to which it refers. */
1096 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
1098 ctf_file_t
*ofp
= fp
;
1099 const ctf_type_t
*tp
;
1101 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1102 return CTF_ERR
; /* errno is set for us. */
1104 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1108 case CTF_K_VOLATILE
:
1110 case CTF_K_RESTRICT
:
1111 return tp
->ctt_type
;
1112 /* Slices store their type in an unusual place. */
1116 const ctf_slice_t
*sp
;
1118 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1122 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1123 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1126 sp
= &dtd
->dtd_u
.dtu_slice
;
1128 return sp
->cts_type
;
1131 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1135 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1136 pointer to the given type, see if we can compute a pointer to the type
1137 resulting from resolving the type down to its base type and use that
1138 instead. This helps with cases where the CTF data includes "struct foo *"
1139 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1141 XXX what about parent containers? */
1144 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
1146 ctf_file_t
*ofp
= fp
;
1149 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1150 return CTF_ERR
; /* errno is set for us. */
1152 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1153 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1155 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1156 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1158 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1159 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1161 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1162 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1164 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1167 /* Return the encoding for the specified INTEGER or FLOAT. */
1170 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1172 ctf_file_t
*ofp
= fp
;
1174 const ctf_type_t
*tp
;
1178 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1179 return -1; /* errno is set for us. */
1181 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1183 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1187 *ep
= dtd
->dtd_u
.dtu_enc
;
1191 const ctf_slice_t
*slice
;
1192 ctf_encoding_t underlying_en
;
1193 ctf_id_t underlying
;
1195 slice
= &dtd
->dtd_u
.dtu_slice
;
1196 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1197 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1199 ep
->cte_format
= underlying_en
.cte_format
;
1200 ep
->cte_offset
= slice
->cts_offset
;
1201 ep
->cte_bits
= slice
->cts_bits
;
1205 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1210 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1212 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1215 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1216 ep
->cte_format
= CTF_INT_ENCODING (data
);
1217 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1218 ep
->cte_bits
= CTF_INT_BITS (data
);
1221 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1222 ep
->cte_format
= CTF_FP_ENCODING (data
);
1223 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1224 ep
->cte_bits
= CTF_FP_BITS (data
);
1228 const ctf_slice_t
*slice
;
1229 ctf_encoding_t underlying_en
;
1230 ctf_id_t underlying
;
1232 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1233 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1234 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1236 ep
->cte_format
= underlying_en
.cte_format
;
1237 ep
->cte_offset
= slice
->cts_offset
;
1238 ep
->cte_bits
= slice
->cts_bits
;
1242 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1249 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
1256 else if (ltype
> rtype
)
1264 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1265 lfp
= lfp
->ctf_parent
;
1267 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1268 rfp
= rfp
->ctf_parent
;
1279 /* Return a boolean value indicating if two types are compatible. This function
1280 returns true if the two types are the same, or if they (or their ultimate
1281 base type) have the same encoding properties, or (for structs / unions /
1282 enums / forward declarations) if they have the same name and (for structs /
1283 unions) member count. */
1286 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
1287 ctf_file_t
*rfp
, ctf_id_t rtype
)
1289 const ctf_type_t
*ltp
, *rtp
;
1290 ctf_encoding_t le
, re
;
1291 ctf_arinfo_t la
, ra
;
1292 uint32_t lkind
, rkind
;
1295 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1298 ltype
= ctf_type_resolve (lfp
, ltype
);
1299 lkind
= ctf_type_kind (lfp
, ltype
);
1301 rtype
= ctf_type_resolve (rfp
, rtype
);
1302 rkind
= ctf_type_kind (rfp
, rtype
);
1304 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1305 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1307 if (ltp
!= NULL
&& rtp
!= NULL
)
1308 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1309 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1311 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1312 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1322 memset (&le
, 0, sizeof (le
));
1323 memset (&re
, 0, sizeof (re
));
1324 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1325 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1326 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1328 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1329 rfp
, ctf_type_reference (rfp
, rtype
)));
1331 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1332 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1333 && la
.ctr_nelems
== ra
.ctr_nelems
1334 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1335 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1338 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1339 == ctf_type_size (rfp
, rtype
)));
1342 int lencoded
, rencoded
;
1343 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1344 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1346 if ((lencoded
!= rencoded
) ||
1347 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1352 return same_names
; /* No other checks required for these type kinds. */
1354 return 0; /* Should not get here since we did a resolve. */
1358 /* Return the number of members in a STRUCT or UNION, or the number of
1359 enumerators in an ENUM. */
1362 ctf_member_count (ctf_file_t
*fp
, ctf_id_t type
)
1364 ctf_file_t
*ofp
= fp
;
1365 const ctf_type_t
*tp
;
1368 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1369 return -1; /* errno is set for us. */
1371 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1372 return -1; /* errno is set for us. */
1374 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1376 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1377 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1379 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1382 /* Return the type and offset for a given member of a STRUCT or UNION. */
1385 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
1386 ctf_membinfo_t
*mip
)
1388 ctf_file_t
*ofp
= fp
;
1389 const ctf_type_t
*tp
;
1391 ssize_t size
, increment
;
1394 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1395 return -1; /* errno is set for us. */
1397 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1398 return -1; /* errno is set for us. */
1400 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1401 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1403 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1404 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1406 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1408 if (size
< CTF_LSTRUCT_THRESH
)
1410 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1413 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1415 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1417 mip
->ctm_type
= mp
->ctm_type
;
1418 mip
->ctm_offset
= mp
->ctm_offset
;
1425 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1428 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1430 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1432 mip
->ctm_type
= lmp
->ctlm_type
;
1433 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1443 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1444 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1446 if (strcmp (dmd
->dmd_name
, name
) == 0)
1448 mip
->ctm_type
= dmd
->dmd_type
;
1449 mip
->ctm_offset
= dmd
->dmd_offset
;
1455 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1458 /* Return the array type, index, and size information for the specified ARRAY. */
1461 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1463 ctf_file_t
*ofp
= fp
;
1464 const ctf_type_t
*tp
;
1465 const ctf_array_t
*ap
;
1466 const ctf_dtdef_t
*dtd
;
1469 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1470 return -1; /* errno is set for us. */
1472 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1473 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1475 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1477 *arp
= dtd
->dtd_u
.dtu_arr
;
1481 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1483 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1484 arp
->ctr_contents
= ap
->cta_contents
;
1485 arp
->ctr_index
= ap
->cta_index
;
1486 arp
->ctr_nelems
= ap
->cta_nelems
;
1491 /* Convert the specified value to the corresponding enum tag name, if a
1492 matching name can be found. Otherwise NULL is returned. */
1495 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1497 ctf_file_t
*ofp
= fp
;
1498 const ctf_type_t
*tp
;
1499 const ctf_enum_t
*ep
;
1500 const ctf_dtdef_t
*dtd
;
1504 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1505 return NULL
; /* errno is set for us. */
1507 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1508 return NULL
; /* errno is set for us. */
1510 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1512 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1516 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1518 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1520 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1522 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1524 if (ep
->cte_value
== value
)
1525 return (ctf_strptr (fp
, ep
->cte_name
));
1532 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1533 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1535 if (dmd
->dmd_value
== value
)
1536 return dmd
->dmd_name
;
1540 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1544 /* Convert the specified enum tag name to the corresponding value, if a
1545 matching name can be found. Otherwise CTF_ERR is returned. */
1548 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1550 ctf_file_t
*ofp
= fp
;
1551 const ctf_type_t
*tp
;
1552 const ctf_enum_t
*ep
;
1553 const ctf_dtdef_t
*dtd
;
1557 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1558 return -1; /* errno is set for us. */
1560 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1561 return -1; /* errno is set for us. */
1563 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1565 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1569 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1571 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1573 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1575 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1577 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1580 *valp
= ep
->cte_value
;
1589 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1590 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1592 if (strcmp (dmd
->dmd_name
, name
) == 0)
1595 *valp
= dmd
->dmd_value
;
1601 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1605 /* Given a type ID relating to a function type, return info on return types and
1606 arg counts for that function. */
1609 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1611 const ctf_type_t
*tp
;
1613 const uint32_t *args
;
1614 const ctf_dtdef_t
*dtd
;
1615 ssize_t size
, increment
;
1617 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1618 return -1; /* errno is set for us. */
1620 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1621 return -1; /* errno is set for us. */
1623 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1624 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1626 if (kind
!= CTF_K_FUNCTION
)
1627 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1629 fip
->ctc_return
= tp
->ctt_type
;
1631 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1633 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1634 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1636 args
= dtd
->dtd_u
.dtu_argv
;
1638 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1640 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1647 /* Given a type ID relating to a function type, return the arguments for the
1651 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1653 const ctf_type_t
*tp
;
1654 const uint32_t *args
;
1655 const ctf_dtdef_t
*dtd
;
1656 ssize_t size
, increment
;
1659 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1660 return -1; /* errno is set for us. */
1662 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1663 return -1; /* errno is set for us. */
1665 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1666 return -1; /* errno is set for us. */
1668 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1670 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1671 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1673 args
= dtd
->dtd_u
.dtu_argv
;
1675 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1681 /* Recursively visit the members of any type. This function is used as the
1682 engine for ctf_type_visit, below. We resolve the input type, recursively
1683 invoke ourself for each type member if the type is a struct or union, and
1684 then invoke the callback function on the current type. If any callback
1685 returns non-zero, we abort and percolate the error code back up to the top. */
1688 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1689 void *arg
, const char *name
, unsigned long offset
, int depth
)
1691 ctf_id_t otype
= type
;
1692 const ctf_type_t
*tp
;
1693 const ctf_dtdef_t
*dtd
;
1694 ssize_t size
, increment
;
1698 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1699 return -1; /* errno is set for us. */
1701 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1702 return -1; /* errno is set for us. */
1704 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1707 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1709 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1712 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1714 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1716 if (size
< CTF_LSTRUCT_THRESH
)
1718 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1721 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1723 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1724 func
, arg
, ctf_strptr (fp
,
1726 offset
+ mp
->ctm_offset
,
1733 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1736 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1738 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1739 func
, arg
, ctf_strptr (fp
,
1741 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1751 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1752 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1754 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1755 dmd
->dmd_name
, dmd
->dmd_offset
,
1764 /* Recursively visit the members of any type. We pass the name, member
1765 type, and offset of each member to the specified callback function. */
1767 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1769 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));