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_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
611 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
620 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
623 return CTF_ERR
; /* errno is set for us. */
626 /* Like ctf_type_resolve(), but traverse down through slices to their contained
630 ctf_type_resolve_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
632 const ctf_type_t
*tp
;
634 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
637 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
638 return CTF_ERR
; /* errno is set for us. */
640 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
641 return ctf_type_reference (fp
, type
);
645 /* Look up a name in the given name table, in the appropriate hash given the
646 kind of the identifier. The name is a raw, undecorated identifier. */
648 ctf_id_t
ctf_lookup_by_rawname (ctf_file_t
*fp
, int kind
, const char *name
)
650 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
653 /* Look up a name in the given name table, in the appropriate hash given the
654 readability state of the dictionary. The name is a raw, undecorated
657 ctf_id_t
ctf_lookup_by_rawhash (ctf_file_t
*fp
, ctf_names_t
*np
, const char *name
)
661 if (fp
->ctf_flags
& LCTF_RDWR
)
662 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
664 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
668 /* Lookup the given type ID and return its name as a new dynamically-allocated
672 ctf_type_aname (ctf_file_t
*fp
, ctf_id_t type
)
675 ctf_decl_node_t
*cdp
;
676 ctf_decl_prec_t prec
, lp
, rp
;
681 if (fp
== NULL
&& type
== CTF_ERR
)
682 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
685 ctf_decl_push (&cd
, fp
, type
);
690 ctf_set_errno (fp
, cd
.cd_err
);
694 /* If the type graph's order conflicts with lexical precedence order
695 for pointers or arrays, then we need to surround the declarations at
696 the corresponding lexical precedence with parentheses. This can
697 result in either a parenthesized pointer (*) as in int (*)() or
698 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
700 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
701 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
703 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
704 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
706 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
708 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
710 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
711 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
713 ctf_file_t
*rfp
= fp
;
714 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
715 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
717 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
718 ctf_decl_sprintf (&cd
, " ");
722 ctf_decl_sprintf (&cd
, "(");
726 switch (cdp
->cd_kind
)
731 /* Integers, floats, and typedefs must always be named types. */
735 ctf_set_errno (fp
, ECTF_CORRUPT
);
740 ctf_decl_sprintf (&cd
, "%s", name
);
743 ctf_decl_sprintf (&cd
, "*");
746 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
752 ctf_id_t
*argv
= NULL
;
754 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
755 goto err
; /* errno is set for us. */
757 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
759 ctf_set_errno (rfp
, errno
);
763 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
764 fi
.ctc_argc
, argv
) < 0)
765 goto err
; /* errno is set for us. */
767 ctf_decl_sprintf (&cd
, "(*) (");
768 for (i
= 0; i
< fi
.ctc_argc
; i
++)
770 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
773 goto err
; /* errno is set for us. */
774 ctf_decl_sprintf (&cd
, "%s", arg
);
777 if ((i
< fi
.ctc_argc
- 1)
778 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
779 ctf_decl_sprintf (&cd
, ", ");
782 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
783 ctf_decl_sprintf (&cd
, "...");
784 ctf_decl_sprintf (&cd
, ")");
797 ctf_decl_sprintf (&cd
, "struct %s", name
);
800 ctf_decl_sprintf (&cd
, "union %s", name
);
803 ctf_decl_sprintf (&cd
, "enum %s", name
);
806 ctf_decl_sprintf (&cd
, "volatile");
809 ctf_decl_sprintf (&cd
, "const");
812 ctf_decl_sprintf (&cd
, "restrict");
815 /* No representation: just changes encoding of contained type,
816 which is not in any case printed. Skip it. */
824 ctf_decl_sprintf (&cd
, ")");
828 (void) ctf_set_errno (fp
, ENOMEM
);
830 buf
= ctf_decl_buf (&cd
);
836 /* Lookup the given type ID and print a string name for it into buf. Return
837 the actual number of bytes (not including \0) needed to format the name. */
840 ctf_type_lname (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
842 char *str
= ctf_type_aname (fp
, type
);
846 return CTF_ERR
; /* errno is set for us. */
849 snprintf (buf
, len
, "%s", str
);
853 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
858 /* Lookup the given type ID and print a string name for it into buf. If buf
859 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
862 ctf_type_name (ctf_file_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
864 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
865 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
868 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
869 The name will live as long as its ctf_file_t does. */
872 ctf_type_name_raw (ctf_file_t
*fp
, ctf_id_t type
)
874 const ctf_type_t
*tp
;
876 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
877 return NULL
; /* errno is set for us. */
879 return ctf_strraw (fp
, tp
->ctt_name
);
882 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
883 new dynamically-allocated string. */
886 ctf_type_aname_raw (ctf_file_t
*fp
, ctf_id_t type
)
888 const char *name
= ctf_type_name_raw (fp
, type
);
891 return strdup (name
);
896 /* Resolve the type down to a base type node, and then return the size
897 of the type storage in bytes. */
900 ctf_type_size (ctf_file_t
*fp
, ctf_id_t type
)
902 const ctf_type_t
*tp
;
906 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
907 return -1; /* errno is set for us. */
909 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
910 return -1; /* errno is set for us. */
912 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
915 return fp
->ctf_dmodel
->ctd_pointer
;
918 return 0; /* Function size is only known by symtab. */
921 return fp
->ctf_dmodel
->ctd_int
;
924 /* ctf_add_array() does not directly encode the element size, but
925 requires the user to multiply to determine the element size.
927 If ctf_get_ctt_size() returns nonzero, then use the recorded
930 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
933 if (ctf_array_info (fp
, type
, &ar
) < 0
934 || (size
= ctf_type_size (fp
, ar
.ctr_contents
)) < 0)
935 return -1; /* errno is set for us. */
937 return size
* ar
.ctr_nelems
;
939 default: /* including slices of enums, etc */
940 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
944 /* Resolve the type down to a base type node, and then return the alignment
945 needed for the type storage in bytes.
947 XXX may need arch-dependent attention. */
950 ctf_type_align (ctf_file_t
*fp
, ctf_id_t type
)
952 const ctf_type_t
*tp
;
953 ctf_file_t
*ofp
= fp
;
956 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
957 return -1; /* errno is set for us. */
959 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
960 return -1; /* errno is set for us. */
962 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
967 return fp
->ctf_dmodel
->ctd_pointer
;
972 if (ctf_array_info (fp
, type
, &r
) < 0)
973 return -1; /* errno is set for us. */
974 return (ctf_type_align (fp
, r
.ctr_contents
));
983 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
985 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
986 ssize_t size
, increment
;
989 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
990 vmp
= (unsigned char *) tp
+ increment
;
992 if (kind
== CTF_K_STRUCT
)
993 n
= MIN (n
, 1); /* Only use first member for structs. */
995 if (size
< CTF_LSTRUCT_THRESH
)
997 const ctf_member_t
*mp
= vmp
;
998 for (; n
!= 0; n
--, mp
++)
1000 ssize_t am
= ctf_type_align (fp
, mp
->ctm_type
);
1001 align
= MAX (align
, (size_t) am
);
1006 const ctf_lmember_t
*lmp
= vmp
;
1007 for (; n
!= 0; n
--, lmp
++)
1009 ssize_t am
= ctf_type_align (fp
, lmp
->ctlm_type
);
1010 align
= MAX (align
, (size_t) am
);
1018 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1019 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1021 ssize_t am
= ctf_type_align (fp
, dmd
->dmd_type
);
1022 align
= MAX (align
, (size_t) am
);
1023 if (kind
== CTF_K_STRUCT
)
1032 return fp
->ctf_dmodel
->ctd_int
;
1034 default: /* including slices of enums, etc */
1035 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1039 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1042 ctf_type_kind_unsliced (ctf_file_t
*fp
, ctf_id_t type
)
1044 const ctf_type_t
*tp
;
1046 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1047 return -1; /* errno is set for us. */
1049 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1052 /* Return the kind (CTF_K_* constant) for the specified type ID.
1053 Slices are considered to be of the same kind as the type sliced. */
1056 ctf_type_kind (ctf_file_t
*fp
, ctf_id_t type
)
1060 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1063 if (kind
== CTF_K_SLICE
)
1065 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1067 kind
= ctf_type_kind_unsliced (fp
, type
);
1073 /* Return the kind of this type, except, for forwards, return the kind of thing
1074 this is a forward to. */
1076 ctf_type_kind_forwarded (ctf_file_t
*fp
, ctf_id_t type
)
1079 const ctf_type_t
*tp
;
1081 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1082 return -1; /* errno is set for us. */
1084 if (kind
!= CTF_K_FORWARD
)
1087 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1088 return -1; /* errno is set for us. */
1090 return tp
->ctt_type
;
1093 /* If the type is one that directly references another type (such as POINTER),
1094 then return the ID of the type to which it refers. */
1097 ctf_type_reference (ctf_file_t
*fp
, ctf_id_t type
)
1099 ctf_file_t
*ofp
= fp
;
1100 const ctf_type_t
*tp
;
1102 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1103 return CTF_ERR
; /* errno is set for us. */
1105 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1109 case CTF_K_VOLATILE
:
1111 case CTF_K_RESTRICT
:
1112 return tp
->ctt_type
;
1113 /* Slices store their type in an unusual place. */
1117 const ctf_slice_t
*sp
;
1119 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1123 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1124 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1127 sp
= &dtd
->dtd_u
.dtu_slice
;
1129 return sp
->cts_type
;
1132 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1136 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1137 pointer to the given type, see if we can compute a pointer to the type
1138 resulting from resolving the type down to its base type and use that
1139 instead. This helps with cases where the CTF data includes "struct foo *"
1140 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1142 XXX what about parent containers? */
1145 ctf_type_pointer (ctf_file_t
*fp
, ctf_id_t type
)
1147 ctf_file_t
*ofp
= fp
;
1150 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1151 return CTF_ERR
; /* errno is set for us. */
1153 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1154 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1156 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1157 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1159 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1160 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1162 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1163 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1165 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1168 /* Return the encoding for the specified INTEGER or FLOAT. */
1171 ctf_type_encoding (ctf_file_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1173 ctf_file_t
*ofp
= fp
;
1175 const ctf_type_t
*tp
;
1179 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1180 return -1; /* errno is set for us. */
1182 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1184 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1188 *ep
= dtd
->dtd_u
.dtu_enc
;
1192 const ctf_slice_t
*slice
;
1193 ctf_encoding_t underlying_en
;
1194 ctf_id_t underlying
;
1196 slice
= &dtd
->dtd_u
.dtu_slice
;
1197 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1198 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1200 ep
->cte_format
= underlying_en
.cte_format
;
1201 ep
->cte_offset
= slice
->cts_offset
;
1202 ep
->cte_bits
= slice
->cts_bits
;
1206 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1211 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1213 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1216 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1217 ep
->cte_format
= CTF_INT_ENCODING (data
);
1218 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1219 ep
->cte_bits
= CTF_INT_BITS (data
);
1222 data
= *(const uint32_t *) ((uintptr_t) tp
+ increment
);
1223 ep
->cte_format
= CTF_FP_ENCODING (data
);
1224 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1225 ep
->cte_bits
= CTF_FP_BITS (data
);
1229 const ctf_slice_t
*slice
;
1230 ctf_encoding_t underlying_en
;
1231 ctf_id_t underlying
;
1233 slice
= (ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1234 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1235 data
= ctf_type_encoding (fp
, underlying
, &underlying_en
);
1237 ep
->cte_format
= underlying_en
.cte_format
;
1238 ep
->cte_offset
= slice
->cts_offset
;
1239 ep
->cte_bits
= slice
->cts_bits
;
1243 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1250 ctf_type_cmp (ctf_file_t
*lfp
, ctf_id_t ltype
, ctf_file_t
*rfp
,
1257 else if (ltype
> rtype
)
1265 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1266 lfp
= lfp
->ctf_parent
;
1268 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1269 rfp
= rfp
->ctf_parent
;
1280 /* Return a boolean value indicating if two types are compatible. This function
1281 returns true if the two types are the same, or if they (or their ultimate
1282 base type) have the same encoding properties, or (for structs / unions /
1283 enums / forward declarations) if they have the same name and (for structs /
1284 unions) member count. */
1287 ctf_type_compat (ctf_file_t
*lfp
, ctf_id_t ltype
,
1288 ctf_file_t
*rfp
, ctf_id_t rtype
)
1290 const ctf_type_t
*ltp
, *rtp
;
1291 ctf_encoding_t le
, re
;
1292 ctf_arinfo_t la
, ra
;
1293 uint32_t lkind
, rkind
;
1296 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1299 ltype
= ctf_type_resolve (lfp
, ltype
);
1300 lkind
= ctf_type_kind (lfp
, ltype
);
1302 rtype
= ctf_type_resolve (rfp
, rtype
);
1303 rkind
= ctf_type_kind (rfp
, rtype
);
1305 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1306 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1308 if (ltp
!= NULL
&& rtp
!= NULL
)
1309 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1310 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1312 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1313 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1323 memset (&le
, 0, sizeof (le
));
1324 memset (&re
, 0, sizeof (re
));
1325 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1326 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1327 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1329 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1330 rfp
, ctf_type_reference (rfp
, rtype
)));
1332 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1333 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1334 && la
.ctr_nelems
== ra
.ctr_nelems
1335 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1336 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1339 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1340 == ctf_type_size (rfp
, rtype
)));
1343 int lencoded
, rencoded
;
1344 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1345 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1347 if ((lencoded
!= rencoded
) ||
1348 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1353 return same_names
; /* No other checks required for these type kinds. */
1355 return 0; /* Should not get here since we did a resolve. */
1359 /* Return the number of members in a STRUCT or UNION, or the number of
1360 enumerators in an ENUM. */
1363 ctf_member_count (ctf_file_t
*fp
, ctf_id_t type
)
1365 ctf_file_t
*ofp
= fp
;
1366 const ctf_type_t
*tp
;
1369 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1370 return -1; /* errno is set for us. */
1372 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1373 return -1; /* errno is set for us. */
1375 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1377 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1378 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1380 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1383 /* Return the type and offset for a given member of a STRUCT or UNION. */
1386 ctf_member_info (ctf_file_t
*fp
, ctf_id_t type
, const char *name
,
1387 ctf_membinfo_t
*mip
)
1389 ctf_file_t
*ofp
= fp
;
1390 const ctf_type_t
*tp
;
1392 ssize_t size
, increment
;
1395 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1396 return -1; /* errno is set for us. */
1398 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1399 return -1; /* errno is set for us. */
1401 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1402 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1404 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1405 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1407 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1409 if (size
< CTF_LSTRUCT_THRESH
)
1411 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1414 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1416 if (strcmp (ctf_strptr (fp
, mp
->ctm_name
), name
) == 0)
1418 mip
->ctm_type
= mp
->ctm_type
;
1419 mip
->ctm_offset
= mp
->ctm_offset
;
1426 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1429 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1431 if (strcmp (ctf_strptr (fp
, lmp
->ctlm_name
), name
) == 0)
1433 mip
->ctm_type
= lmp
->ctlm_type
;
1434 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1444 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1445 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1447 if (strcmp (dmd
->dmd_name
, name
) == 0)
1449 mip
->ctm_type
= dmd
->dmd_type
;
1450 mip
->ctm_offset
= dmd
->dmd_offset
;
1456 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1459 /* Return the array type, index, and size information for the specified ARRAY. */
1462 ctf_array_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1464 ctf_file_t
*ofp
= fp
;
1465 const ctf_type_t
*tp
;
1466 const ctf_array_t
*ap
;
1467 const ctf_dtdef_t
*dtd
;
1470 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1471 return -1; /* errno is set for us. */
1473 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1474 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1476 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1478 *arp
= dtd
->dtd_u
.dtu_arr
;
1482 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1484 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1485 arp
->ctr_contents
= ap
->cta_contents
;
1486 arp
->ctr_index
= ap
->cta_index
;
1487 arp
->ctr_nelems
= ap
->cta_nelems
;
1492 /* Convert the specified value to the corresponding enum tag name, if a
1493 matching name can be found. Otherwise NULL is returned. */
1496 ctf_enum_name (ctf_file_t
*fp
, ctf_id_t type
, int value
)
1498 ctf_file_t
*ofp
= fp
;
1499 const ctf_type_t
*tp
;
1500 const ctf_enum_t
*ep
;
1501 const ctf_dtdef_t
*dtd
;
1505 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1506 return NULL
; /* errno is set for us. */
1508 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1509 return NULL
; /* errno is set for us. */
1511 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1513 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1517 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1519 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1521 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1523 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1525 if (ep
->cte_value
== value
)
1526 return (ctf_strptr (fp
, ep
->cte_name
));
1533 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1534 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1536 if (dmd
->dmd_value
== value
)
1537 return dmd
->dmd_name
;
1541 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1545 /* Convert the specified enum tag name to the corresponding value, if a
1546 matching name can be found. Otherwise CTF_ERR is returned. */
1549 ctf_enum_value (ctf_file_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1551 ctf_file_t
*ofp
= fp
;
1552 const ctf_type_t
*tp
;
1553 const ctf_enum_t
*ep
;
1554 const ctf_dtdef_t
*dtd
;
1558 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1559 return -1; /* errno is set for us. */
1561 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1562 return -1; /* errno is set for us. */
1564 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1566 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1570 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1572 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1574 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1576 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1578 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1581 *valp
= ep
->cte_value
;
1590 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1591 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1593 if (strcmp (dmd
->dmd_name
, name
) == 0)
1596 *valp
= dmd
->dmd_value
;
1602 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1606 /* Given a type ID relating to a function type, return info on return types and
1607 arg counts for that function. */
1610 ctf_func_type_info (ctf_file_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1612 const ctf_type_t
*tp
;
1614 const uint32_t *args
;
1615 const ctf_dtdef_t
*dtd
;
1616 ssize_t size
, increment
;
1618 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1619 return -1; /* errno is set for us. */
1621 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1622 return -1; /* errno is set for us. */
1624 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1625 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1627 if (kind
!= CTF_K_FUNCTION
)
1628 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1630 fip
->ctc_return
= tp
->ctt_type
;
1632 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1634 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1635 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1637 args
= dtd
->dtd_u
.dtu_argv
;
1639 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1641 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1648 /* Given a type ID relating to a function type, return the arguments for the
1652 ctf_func_type_args (ctf_file_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1654 const ctf_type_t
*tp
;
1655 const uint32_t *args
;
1656 const ctf_dtdef_t
*dtd
;
1657 ssize_t size
, increment
;
1660 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1661 return -1; /* errno is set for us. */
1663 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1664 return -1; /* errno is set for us. */
1666 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1667 return -1; /* errno is set for us. */
1669 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1671 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1672 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1674 args
= dtd
->dtd_u
.dtu_argv
;
1676 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1682 /* Recursively visit the members of any type. This function is used as the
1683 engine for ctf_type_visit, below. We resolve the input type, recursively
1684 invoke ourself for each type member if the type is a struct or union, and
1685 then invoke the callback function on the current type. If any callback
1686 returns non-zero, we abort and percolate the error code back up to the top. */
1689 ctf_type_rvisit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1690 void *arg
, const char *name
, unsigned long offset
, int depth
)
1692 ctf_id_t otype
= type
;
1693 const ctf_type_t
*tp
;
1694 const ctf_dtdef_t
*dtd
;
1695 ssize_t size
, increment
;
1699 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1700 return -1; /* errno is set for us. */
1702 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1703 return -1; /* errno is set for us. */
1705 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1708 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1710 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1713 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1715 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1717 if (size
< CTF_LSTRUCT_THRESH
)
1719 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1722 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1724 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1725 func
, arg
, ctf_strptr (fp
,
1727 offset
+ mp
->ctm_offset
,
1734 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1737 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1739 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1740 func
, arg
, ctf_strptr (fp
,
1742 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1752 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1753 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1755 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1756 dmd
->dmd_name
, dmd
->dmd_offset
,
1765 /* Recursively visit the members of any type. We pass the name, member
1766 type, and offset of each member to the specified callback function. */
1768 ctf_type_visit (ctf_file_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1770 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));