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
)
49 while ((offset
= ctf_member_next (fp
, type
, &i
, &name
, &membtype
, 0)) >= 0)
52 if ((rc
= func (name
, membtype
, offset
, arg
)) != 0)
58 if (ctf_errno (fp
) != ECTF_NEXT_END
)
59 return -1; /* errno is set for us. */
64 /* Iterate over the members of a STRUCT or UNION, returning each member's
65 offset and optionally name and member type in turn. On end-of-iteration,
66 returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */
69 ctf_member_next (ctf_dict_t
*fp
, ctf_id_t type
, ctf_next_t
**it
,
70 const char **name
, ctf_id_t
*membtype
, int flags
)
83 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
84 return -1; /* errno is set for us. */
86 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
87 return -1; /* errno is set for us. */
89 if ((i
= ctf_next_create ()) == NULL
)
90 return ctf_set_errno (ofp
, ENOMEM
);
93 (void) ctf_get_ctt_size (fp
, tp
, &i
->ctn_size
, &increment
);
94 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
96 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
99 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
102 dtd
= ctf_dynamic_type (fp
, type
);
103 i
->ctn_iter_fun
= (void (*) (void)) ctf_member_next
;
105 /* We depend below on the RDWR state indicating whether the DTD-related
106 fields or the DMD-related fields have been initialized. */
108 assert ((dtd
&& (fp
->ctf_flags
& LCTF_RDWR
))
109 || (!dtd
&& (!(fp
->ctf_flags
& LCTF_RDWR
))));
113 i
->ctn_n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
115 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
116 i
->u
.ctn_mp
= (const ctf_member_t
*) ((uintptr_t) tp
+ increment
);
118 i
->u
.ctn_lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+ increment
);
121 i
->u
.ctn_dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
126 if ((void (*) (void)) ctf_member_next
!= i
->ctn_iter_fun
)
127 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFUN
));
129 if (ofp
!= i
->cu
.ctn_fp
)
130 return (ctf_set_errno (ofp
, ECTF_NEXT_WRONGFP
));
132 /* Resolve to the native dict of this type. */
133 if ((fp
= ctf_get_dict (ofp
, type
)) == NULL
)
134 return (ctf_set_errno (ofp
, ECTF_NOPARENT
));
136 /* When we hit an unnamed struct/union member, we set ctn_type to indicate
137 that we are inside one, then return the unnamed member: on the next call,
138 we must skip over top-level member iteration in favour of iteration within
139 the sub-struct until it later turns out that that iteration has ended. */
144 if (!(fp
->ctf_flags
& LCTF_RDWR
))
149 if (i
->ctn_size
< CTF_LSTRUCT_THRESH
)
151 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_mp
->ctm_name
);
156 *membtype
= i
->u
.ctn_mp
->ctm_type
;
157 offset
= i
->u
.ctn_mp
->ctm_offset
;
160 && (ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_STRUCT
161 || ctf_type_kind (fp
, i
->u
.ctn_mp
->ctm_type
) == CTF_K_UNION
))
162 i
->ctn_type
= i
->u
.ctn_mp
->ctm_type
;
168 const char *membname
= ctf_strptr (fp
, i
->u
.ctn_lmp
->ctlm_name
);
173 *membtype
= i
->u
.ctn_lmp
->ctlm_type
;
174 offset
= (unsigned long) CTF_LMEM_OFFSET (i
->u
.ctn_lmp
);
177 && (ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_STRUCT
178 || ctf_type_kind (fp
, i
->u
.ctn_lmp
->ctlm_type
) == CTF_K_UNION
))
179 i
->ctn_type
= i
->u
.ctn_lmp
->ctlm_type
;
187 if (i
->u
.ctn_dmd
== NULL
)
189 /* The dmd contains a NULL for unnamed dynamic members. Don't inflict
190 this on our callers. */
193 if (i
->u
.ctn_dmd
->dmd_name
)
194 *name
= i
->u
.ctn_dmd
->dmd_name
;
199 *membtype
= i
->u
.ctn_dmd
->dmd_type
;
200 offset
= i
->u
.ctn_dmd
->dmd_offset
;
202 if (i
->u
.ctn_dmd
->dmd_name
== NULL
203 && (ctf_type_kind (fp
, i
->u
.ctn_dmd
->dmd_type
) == CTF_K_STRUCT
204 || ctf_type_kind (fp
, i
->u
.ctn_dmd
->dmd_type
) == CTF_K_UNION
))
205 i
->ctn_type
= i
->u
.ctn_dmd
->dmd_type
;
207 i
->u
.ctn_dmd
= ctf_list_next (i
->u
.ctn_dmd
);
210 /* The callers might want automatic recursive sub-struct traversal. */
211 if (!(flags
& CTF_MN_RECURSE
))
214 /* Sub-struct traversal starting? Take note of the offset of this member,
215 for later boosting of sub-struct members' offsets. */
217 i
->ctn_increment
= offset
;
219 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
222 ssize_t ret
= ctf_member_next (fp
, i
->ctn_type
, &i
->ctn_next
, name
,
226 return ret
+ i
->ctn_increment
;
228 if (ctf_errno (fp
) != ECTF_NEXT_END
)
230 ctf_next_destroy (i
);
233 return ret
; /* errno is set for us. */
236 if (!ctf_assert (fp
, (i
->ctn_next
== NULL
)))
237 return -1; /* errno is set for us. */
240 /* This sub-struct has ended: on to the next real member. */
247 ctf_next_destroy (i
);
249 return ctf_set_errno (ofp
, ECTF_NEXT_END
);
252 /* Iterate over the members of an ENUM. We pass the string name and associated
253 integer value of each enum element to the specified callback function. */
256 ctf_enum_iter (ctf_dict_t
*fp
, ctf_id_t type
, ctf_enum_f
*func
, void *arg
)
258 ctf_next_t
*i
= NULL
;
262 while ((name
= ctf_enum_next (fp
, type
, &i
, &val
)) != NULL
)
265 if ((rc
= func (name
, val
, arg
)) != 0)
267 ctf_next_destroy (i
);
271 if (ctf_errno (fp
) != ECTF_NEXT_END
)
272 return -1; /* errno is set for us. */
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_next_t
*i
= NULL
;
404 while ((type
= ctf_type_next (fp
, &i
, NULL
, 0)) != CTF_ERR
)
407 if ((rc
= func (type
, arg
)) != 0)
409 ctf_next_destroy (i
);
413 if (ctf_errno (fp
) != ECTF_NEXT_END
)
414 return -1; /* errno is set for us. */
419 /* Iterate over every type in the given CTF dict, user-visible or not.
420 We pass the type ID of each type to the specified callback function.
422 Does not traverse parent types: you have to do that explicitly. This is by
423 design, to avoid traversing them more than once if traversing many children
424 of a single parent. */
427 ctf_type_iter_all (ctf_dict_t
*fp
, ctf_type_all_f
*func
, void *arg
)
429 ctf_next_t
*i
= NULL
;
433 while ((type
= ctf_type_next (fp
, &i
, &flag
, 1)) != CTF_ERR
)
436 if ((rc
= func (type
, flag
, arg
)) != 0)
438 ctf_next_destroy (i
);
442 if (ctf_errno (fp
) != ECTF_NEXT_END
)
443 return -1; /* errno is set for us. */
448 /* Iterate over every type in the given CTF dict, optionally including
449 non-user-visible types, returning each type ID and hidden flag in turn.
450 Returns CTF_ERR on end of iteration or error.
452 Does not traverse parent types: you have to do that explicitly. This is by
453 design, to avoid traversing them more than once if traversing many children
454 of a single parent. */
457 ctf_type_next (ctf_dict_t
*fp
, ctf_next_t
**it
, int *flag
, int want_hidden
)
463 if ((i
= ctf_next_create ()) == NULL
)
464 return ctf_set_errno (fp
, ENOMEM
);
468 i
->ctn_iter_fun
= (void (*) (void)) ctf_type_next
;
472 if ((void (*) (void)) ctf_type_next
!= i
->ctn_iter_fun
)
473 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
475 if (fp
!= i
->cu
.ctn_fp
)
476 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
478 while (i
->ctn_type
<= fp
->ctf_typemax
)
480 const ctf_type_t
*tp
= LCTF_INDEX_TO_TYPEPTR (fp
, i
->ctn_type
);
482 if ((!want_hidden
) && (!LCTF_INFO_ISROOT (fp
, tp
->ctt_info
)))
489 *flag
= LCTF_INFO_ISROOT (fp
, tp
->ctt_info
);
490 return LCTF_INDEX_TO_TYPE (fp
, i
->ctn_type
++, fp
->ctf_flags
& LCTF_CHILD
);
492 ctf_next_destroy (i
);
494 return ctf_set_errno (fp
, ECTF_NEXT_END
);
497 /* Iterate over every variable in the given CTF dict, in arbitrary order.
498 We pass the name of each variable to the specified callback function. */
501 ctf_variable_iter (ctf_dict_t
*fp
, ctf_variable_f
*func
, void *arg
)
503 ctf_next_t
*i
= NULL
;
507 while ((type
= ctf_variable_next (fp
, &i
, &name
)) != CTF_ERR
)
510 if ((rc
= func (name
, type
, arg
)) != 0)
512 ctf_next_destroy (i
);
516 if (ctf_errno (fp
) != ECTF_NEXT_END
)
517 return -1; /* errno is set for us. */
522 /* Iterate over every variable in the given CTF dict, in arbitrary order,
523 returning the name and type of each variable in turn. The name argument is
524 not optional. Returns CTF_ERR on end of iteration or error. */
527 ctf_variable_next (ctf_dict_t
*fp
, ctf_next_t
**it
, const char **name
)
531 if ((fp
->ctf_flags
& LCTF_CHILD
) && (fp
->ctf_parent
== NULL
))
532 return (ctf_set_errno (fp
, ECTF_NOPARENT
));
536 if ((i
= ctf_next_create ()) == NULL
)
537 return ctf_set_errno (fp
, ENOMEM
);
540 i
->ctn_iter_fun
= (void (*) (void)) ctf_variable_next
;
541 if (fp
->ctf_flags
& LCTF_RDWR
)
542 i
->u
.ctn_dvd
= ctf_list_next (&fp
->ctf_dvdefs
);
546 if ((void (*) (void)) ctf_variable_next
!= i
->ctn_iter_fun
)
547 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFUN
));
549 if (fp
!= i
->cu
.ctn_fp
)
550 return (ctf_set_errno (fp
, ECTF_NEXT_WRONGFP
));
552 if (!(fp
->ctf_flags
& LCTF_RDWR
))
554 if (i
->ctn_n
>= fp
->ctf_nvars
)
557 *name
= ctf_strptr (fp
, fp
->ctf_vars
[i
->ctn_n
].ctv_name
);
558 return fp
->ctf_vars
[i
->ctn_n
++].ctv_type
;
564 if (i
->u
.ctn_dvd
== NULL
)
567 *name
= i
->u
.ctn_dvd
->dvd_name
;
568 id
= i
->u
.ctn_dvd
->dvd_type
;
569 i
->u
.ctn_dvd
= ctf_list_next (i
->u
.ctn_dvd
);
574 ctf_next_destroy (i
);
576 return ctf_set_errno (fp
, ECTF_NEXT_END
);
579 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
580 RESTRICT nodes until we reach a "base" type node. This is useful when
581 we want to follow a type ID to a node that has members or a size. To guard
582 against infinite loops, we implement simplified cycle detection and check
583 each link against itself, the previous node, and the topmost node.
585 Does not drill down through slices to their contained type.
587 Callers of this function must not presume that a type it returns must have a
588 valid ctt_size: forwards do not, and must be separately handled. */
591 ctf_type_resolve (ctf_dict_t
*fp
, ctf_id_t type
)
593 ctf_id_t prev
= type
, otype
= type
;
594 ctf_dict_t
*ofp
= fp
;
595 const ctf_type_t
*tp
;
598 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
600 while ((tp
= ctf_lookup_by_id (&fp
, type
)) != NULL
)
602 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
608 if (tp
->ctt_type
== type
|| tp
->ctt_type
== otype
609 || tp
->ctt_type
== prev
)
611 ctf_err_warn (ofp
, 0, ECTF_CORRUPT
, _("type %lx cycle detected"),
613 return (ctf_set_errno (ofp
, ECTF_CORRUPT
));
622 return (ctf_set_errno (ofp
, ECTF_NONREPRESENTABLE
));
625 return CTF_ERR
; /* errno is set for us. */
628 /* Like ctf_type_resolve(), but traverse down through slices to their contained
632 ctf_type_resolve_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
634 const ctf_type_t
*tp
;
636 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
639 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
640 return CTF_ERR
; /* errno is set for us. */
642 if ((LCTF_INFO_KIND (fp
, tp
->ctt_info
)) == CTF_K_SLICE
)
643 return ctf_type_reference (fp
, type
);
647 /* Return the native dict of a given type: if called on a child and the
648 type is in the parent, return the parent. Needed if you plan to access
649 the type directly, without using the API. */
651 ctf_get_dict (ctf_dict_t
*fp
, ctf_id_t type
)
653 if ((fp
->ctf_flags
& LCTF_CHILD
) && LCTF_TYPE_ISPARENT (fp
, type
))
654 return fp
->ctf_parent
;
659 /* Look up a name in the given name table, in the appropriate hash given the
660 kind of the identifier. The name is a raw, undecorated identifier. */
662 ctf_id_t
ctf_lookup_by_rawname (ctf_dict_t
*fp
, int kind
, const char *name
)
664 return ctf_lookup_by_rawhash (fp
, ctf_name_table (fp
, kind
), name
);
667 /* Look up a name in the given name table, in the appropriate hash given the
668 readability state of the dictionary. The name is a raw, undecorated
671 ctf_id_t
ctf_lookup_by_rawhash (ctf_dict_t
*fp
, ctf_names_t
*np
, const char *name
)
675 if (fp
->ctf_flags
& LCTF_RDWR
)
676 id
= (ctf_id_t
) (uintptr_t) ctf_dynhash_lookup (np
->ctn_writable
, name
);
678 id
= ctf_hash_lookup_type (np
->ctn_readonly
, fp
, name
);
682 /* Lookup the given type ID and return its name as a new dynamically-allocated
686 ctf_type_aname (ctf_dict_t
*fp
, ctf_id_t type
)
689 ctf_decl_node_t
*cdp
;
690 ctf_decl_prec_t prec
, lp
, rp
;
695 if (fp
== NULL
&& type
== CTF_ERR
)
696 return NULL
; /* Simplify caller code by permitting CTF_ERR. */
699 ctf_decl_push (&cd
, fp
, type
);
704 ctf_set_errno (fp
, cd
.cd_err
);
708 /* If the type graph's order conflicts with lexical precedence order
709 for pointers or arrays, then we need to surround the declarations at
710 the corresponding lexical precedence with parentheses. This can
711 result in either a parenthesized pointer (*) as in int (*)() or
712 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
714 ptr
= cd
.cd_order
[CTF_PREC_POINTER
] > CTF_PREC_POINTER
;
715 arr
= cd
.cd_order
[CTF_PREC_ARRAY
] > CTF_PREC_ARRAY
;
717 rp
= arr
? CTF_PREC_ARRAY
: ptr
? CTF_PREC_POINTER
: -1;
718 lp
= ptr
? CTF_PREC_POINTER
: arr
? CTF_PREC_ARRAY
: -1;
720 k
= CTF_K_POINTER
; /* Avoid leading whitespace (see below). */
722 for (prec
= CTF_PREC_BASE
; prec
< CTF_PREC_MAX
; prec
++)
724 for (cdp
= ctf_list_next (&cd
.cd_nodes
[prec
]);
725 cdp
!= NULL
; cdp
= ctf_list_next (cdp
))
727 ctf_dict_t
*rfp
= fp
;
728 const ctf_type_t
*tp
= ctf_lookup_by_id (&rfp
, cdp
->cd_type
);
729 const char *name
= ctf_strptr (rfp
, tp
->ctt_name
);
731 if (k
!= CTF_K_POINTER
&& k
!= CTF_K_ARRAY
)
732 ctf_decl_sprintf (&cd
, " ");
736 ctf_decl_sprintf (&cd
, "(");
740 switch (cdp
->cd_kind
)
745 /* Integers, floats, and typedefs must always be named types. */
749 ctf_set_errno (fp
, ECTF_CORRUPT
);
754 ctf_decl_sprintf (&cd
, "%s", name
);
757 ctf_decl_sprintf (&cd
, "*");
760 ctf_decl_sprintf (&cd
, "[%u]", cdp
->cd_n
);
766 ctf_id_t
*argv
= NULL
;
768 if (ctf_func_type_info (rfp
, cdp
->cd_type
, &fi
) < 0)
769 goto err
; /* errno is set for us. */
771 if ((argv
= calloc (fi
.ctc_argc
, sizeof (ctf_id_t
*))) == NULL
)
773 ctf_set_errno (rfp
, errno
);
777 if (ctf_func_type_args (rfp
, cdp
->cd_type
,
778 fi
.ctc_argc
, argv
) < 0)
779 goto err
; /* errno is set for us. */
781 ctf_decl_sprintf (&cd
, "(*) (");
782 for (i
= 0; i
< fi
.ctc_argc
; i
++)
784 char *arg
= ctf_type_aname (rfp
, argv
[i
]);
787 goto err
; /* errno is set for us. */
788 ctf_decl_sprintf (&cd
, "%s", arg
);
791 if ((i
< fi
.ctc_argc
- 1)
792 || (fi
.ctc_flags
& CTF_FUNC_VARARG
))
793 ctf_decl_sprintf (&cd
, ", ");
796 if (fi
.ctc_flags
& CTF_FUNC_VARARG
)
797 ctf_decl_sprintf (&cd
, "...");
798 ctf_decl_sprintf (&cd
, ")");
810 ctf_decl_sprintf (&cd
, "struct %s", name
);
813 ctf_decl_sprintf (&cd
, "union %s", name
);
816 ctf_decl_sprintf (&cd
, "enum %s", name
);
820 switch (ctf_type_kind_forwarded (fp
, cdp
->cd_type
))
823 ctf_decl_sprintf (&cd
, "struct %s", name
);
826 ctf_decl_sprintf (&cd
, "union %s", name
);
829 ctf_decl_sprintf (&cd
, "enum %s", name
);
832 ctf_set_errno (fp
, ECTF_CORRUPT
);
839 ctf_decl_sprintf (&cd
, "volatile");
842 ctf_decl_sprintf (&cd
, "const");
845 ctf_decl_sprintf (&cd
, "restrict");
853 ctf_decl_sprintf (&cd
, ")");
857 (void) ctf_set_errno (fp
, ENOMEM
);
859 buf
= ctf_decl_buf (&cd
);
865 /* Lookup the given type ID and print a string name for it into buf. Return
866 the actual number of bytes (not including \0) needed to format the name. */
869 ctf_type_lname (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
871 char *str
= ctf_type_aname (fp
, type
);
875 return CTF_ERR
; /* errno is set for us. */
878 snprintf (buf
, len
, "%s", str
);
882 (void) ctf_set_errno (fp
, ECTF_NAMELEN
);
887 /* Lookup the given type ID and print a string name for it into buf. If buf
888 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
891 ctf_type_name (ctf_dict_t
*fp
, ctf_id_t type
, char *buf
, size_t len
)
893 ssize_t rv
= ctf_type_lname (fp
, type
, buf
, len
);
894 return (rv
>= 0 && (size_t) rv
< len
? buf
: NULL
);
897 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
898 The name will live as long as its ctf_dict_t does.
900 The only decoration is that a NULL return always means an error: nameless
901 types return a null string. */
904 ctf_type_name_raw (ctf_dict_t
*fp
, ctf_id_t type
)
906 const ctf_type_t
*tp
;
908 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
909 return NULL
; /* errno is set for us. */
911 if (tp
->ctt_name
== 0)
914 return ctf_strraw (fp
, tp
->ctt_name
);
917 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
918 new dynamically-allocated string. */
921 ctf_type_aname_raw (ctf_dict_t
*fp
, ctf_id_t type
)
923 const char *name
= ctf_type_name_raw (fp
, type
);
926 return strdup (name
);
931 /* Resolve the type down to a base type node, and then return the size
932 of the type storage in bytes. */
935 ctf_type_size (ctf_dict_t
*fp
, ctf_id_t type
)
937 ctf_dict_t
*ofp
= fp
;
938 const ctf_type_t
*tp
;
942 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
943 return -1; /* errno is set for us. */
945 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
946 return -1; /* errno is set for us. */
948 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
951 return fp
->ctf_dmodel
->ctd_pointer
;
954 return 0; /* Function size is only known by symtab. */
957 return fp
->ctf_dmodel
->ctd_int
;
960 /* ctf_add_array() does not directly encode the element size, but
961 requires the user to multiply to determine the element size.
963 If ctf_get_ctt_size() returns nonzero, then use the recorded
966 if ((size
= ctf_get_ctt_size (fp
, tp
, NULL
, NULL
)) > 0)
969 if (ctf_array_info (ofp
, type
, &ar
) < 0
970 || (size
= ctf_type_size (ofp
, ar
.ctr_contents
)) < 0)
971 return -1; /* errno is set for us. */
973 return size
* ar
.ctr_nelems
;
976 /* Forwards do not have a meaningful size. */
977 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
979 default: /* including slices of enums, etc */
980 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
984 /* Resolve the type down to a base type node, and then return the alignment
985 needed for the type storage in bytes.
987 XXX may need arch-dependent attention. */
990 ctf_type_align (ctf_dict_t
*fp
, ctf_id_t type
)
992 const ctf_type_t
*tp
;
993 ctf_dict_t
*ofp
= fp
;
996 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
997 return -1; /* errno is set for us. */
999 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1000 return -1; /* errno is set for us. */
1002 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1006 case CTF_K_FUNCTION
:
1007 return fp
->ctf_dmodel
->ctd_pointer
;
1012 if (ctf_array_info (ofp
, type
, &r
) < 0)
1013 return -1; /* errno is set for us. */
1014 return (ctf_type_align (ofp
, r
.ctr_contents
));
1023 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1025 uint32_t n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1026 ssize_t size
, increment
;
1029 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1030 vmp
= (unsigned char *) tp
+ increment
;
1032 if (kind
== CTF_K_STRUCT
)
1033 n
= MIN (n
, 1); /* Only use first member for structs. */
1035 if (size
< CTF_LSTRUCT_THRESH
)
1037 const ctf_member_t
*mp
= vmp
;
1038 for (; n
!= 0; n
--, mp
++)
1040 ssize_t am
= ctf_type_align (ofp
, mp
->ctm_type
);
1041 align
= MAX (align
, (size_t) am
);
1046 const ctf_lmember_t
*lmp
= vmp
;
1047 for (; n
!= 0; n
--, lmp
++)
1049 ssize_t am
= ctf_type_align (ofp
, lmp
->ctlm_type
);
1050 align
= MAX (align
, (size_t) am
);
1058 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1059 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1061 ssize_t am
= ctf_type_align (ofp
, dmd
->dmd_type
);
1062 align
= MAX (align
, (size_t) am
);
1063 if (kind
== CTF_K_STRUCT
)
1072 return fp
->ctf_dmodel
->ctd_int
;
1075 /* Forwards do not have a meaningful alignment. */
1076 return (ctf_set_errno (ofp
, ECTF_INCOMPLETE
));
1078 default: /* including slices of enums, etc */
1079 return (ctf_get_ctt_size (fp
, tp
, NULL
, NULL
));
1083 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1086 ctf_type_kind_unsliced (ctf_dict_t
*fp
, ctf_id_t type
)
1088 const ctf_type_t
*tp
;
1090 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1091 return -1; /* errno is set for us. */
1093 return (LCTF_INFO_KIND (fp
, tp
->ctt_info
));
1096 /* Return the kind (CTF_K_* constant) for the specified type ID.
1097 Slices are considered to be of the same kind as the type sliced. */
1100 ctf_type_kind (ctf_dict_t
*fp
, ctf_id_t type
)
1104 if ((kind
= ctf_type_kind_unsliced (fp
, type
)) < 0)
1107 if (kind
== CTF_K_SLICE
)
1109 if ((type
= ctf_type_reference (fp
, type
)) == CTF_ERR
)
1111 kind
= ctf_type_kind_unsliced (fp
, type
);
1117 /* Return the kind of this type, except, for forwards, return the kind of thing
1118 this is a forward to. */
1120 ctf_type_kind_forwarded (ctf_dict_t
*fp
, ctf_id_t type
)
1123 const ctf_type_t
*tp
;
1125 if ((kind
= ctf_type_kind (fp
, type
)) < 0)
1126 return -1; /* errno is set for us. */
1128 if (kind
!= CTF_K_FORWARD
)
1131 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1132 return -1; /* errno is set for us. */
1134 return tp
->ctt_type
;
1137 /* If the type is one that directly references another type (such as POINTER),
1138 then return the ID of the type to which it refers. */
1141 ctf_type_reference (ctf_dict_t
*fp
, ctf_id_t type
)
1143 ctf_dict_t
*ofp
= fp
;
1144 const ctf_type_t
*tp
;
1146 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1147 return CTF_ERR
; /* errno is set for us. */
1149 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1153 case CTF_K_VOLATILE
:
1155 case CTF_K_RESTRICT
:
1156 return tp
->ctt_type
;
1157 /* Slices store their type in an unusual place. */
1161 const ctf_slice_t
*sp
;
1163 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1167 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1168 sp
= (const ctf_slice_t
*) ((uintptr_t) tp
+ increment
);
1171 sp
= (const ctf_slice_t
*) dtd
->dtd_vlen
;
1173 return sp
->cts_type
;
1176 return (ctf_set_errno (ofp
, ECTF_NOTREF
));
1180 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1181 pointer to the given type, see if we can compute a pointer to the type
1182 resulting from resolving the type down to its base type and use that
1183 instead. This helps with cases where the CTF data includes "struct foo *"
1184 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1186 XXX what about parent dicts? */
1189 ctf_type_pointer (ctf_dict_t
*fp
, ctf_id_t type
)
1191 ctf_dict_t
*ofp
= fp
;
1194 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1195 return CTF_ERR
; /* errno is set for us. */
1197 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1198 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1200 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1201 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1203 if (ctf_lookup_by_id (&fp
, type
) == NULL
)
1204 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1206 if ((ntype
= fp
->ctf_ptrtab
[LCTF_TYPE_TO_INDEX (fp
, type
)]) != 0)
1207 return (LCTF_INDEX_TO_TYPE (fp
, ntype
, (fp
->ctf_flags
& LCTF_CHILD
)));
1209 return (ctf_set_errno (ofp
, ECTF_NOTYPE
));
1212 /* Return the encoding for the specified INTEGER or FLOAT. */
1215 ctf_type_encoding (ctf_dict_t
*fp
, ctf_id_t type
, ctf_encoding_t
*ep
)
1217 ctf_dict_t
*ofp
= fp
;
1219 const ctf_type_t
*tp
;
1221 const unsigned char *vlen
;
1224 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1225 return -1; /* errno is set for us. */
1227 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1228 vlen
= dtd
->dtd_vlen
;
1231 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1232 vlen
= (const unsigned char *) ((uintptr_t) tp
+ increment
);
1235 switch (LCTF_INFO_KIND (fp
, tp
->ctt_info
))
1238 data
= *(const uint32_t *) vlen
;
1239 ep
->cte_format
= CTF_INT_ENCODING (data
);
1240 ep
->cte_offset
= CTF_INT_OFFSET (data
);
1241 ep
->cte_bits
= CTF_INT_BITS (data
);
1244 data
= *(const uint32_t *) vlen
;
1245 ep
->cte_format
= CTF_FP_ENCODING (data
);
1246 ep
->cte_offset
= CTF_FP_OFFSET (data
);
1247 ep
->cte_bits
= CTF_FP_BITS (data
);
1251 const ctf_slice_t
*slice
;
1252 ctf_encoding_t underlying_en
;
1253 ctf_id_t underlying
;
1255 slice
= (ctf_slice_t
*) vlen
;
1256 underlying
= ctf_type_resolve (fp
, slice
->cts_type
);
1257 if (ctf_type_encoding (fp
, underlying
, &underlying_en
) < 0)
1258 return -1; /* errno is set for us. */
1260 ep
->cte_format
= underlying_en
.cte_format
;
1261 ep
->cte_offset
= slice
->cts_offset
;
1262 ep
->cte_bits
= slice
->cts_bits
;
1266 return (ctf_set_errno (ofp
, ECTF_NOTINTFP
));
1273 ctf_type_cmp (ctf_dict_t
*lfp
, ctf_id_t ltype
, ctf_dict_t
*rfp
,
1280 else if (ltype
> rtype
)
1288 if (LCTF_TYPE_ISPARENT (lfp
, ltype
) && lfp
->ctf_parent
!= NULL
)
1289 lfp
= lfp
->ctf_parent
;
1291 if (LCTF_TYPE_ISPARENT (rfp
, rtype
) && rfp
->ctf_parent
!= NULL
)
1292 rfp
= rfp
->ctf_parent
;
1303 /* Return a boolean value indicating if two types are compatible. This function
1304 returns true if the two types are the same, or if they (or their ultimate
1305 base type) have the same encoding properties, or (for structs / unions /
1306 enums / forward declarations) if they have the same name and (for structs /
1307 unions) member count. */
1310 ctf_type_compat (ctf_dict_t
*lfp
, ctf_id_t ltype
,
1311 ctf_dict_t
*rfp
, ctf_id_t rtype
)
1313 const ctf_type_t
*ltp
, *rtp
;
1314 ctf_encoding_t le
, re
;
1315 ctf_arinfo_t la
, ra
;
1316 uint32_t lkind
, rkind
;
1319 if (ctf_type_cmp (lfp
, ltype
, rfp
, rtype
) == 0)
1322 ltype
= ctf_type_resolve (lfp
, ltype
);
1323 lkind
= ctf_type_kind (lfp
, ltype
);
1325 rtype
= ctf_type_resolve (rfp
, rtype
);
1326 rkind
= ctf_type_kind (rfp
, rtype
);
1328 ltp
= ctf_lookup_by_id (&lfp
, ltype
);
1329 rtp
= ctf_lookup_by_id (&rfp
, rtype
);
1331 if (ltp
!= NULL
&& rtp
!= NULL
)
1332 same_names
= (strcmp (ctf_strptr (lfp
, ltp
->ctt_name
),
1333 ctf_strptr (rfp
, rtp
->ctt_name
)) == 0);
1335 if (((lkind
== CTF_K_ENUM
) && (rkind
== CTF_K_INTEGER
)) ||
1336 ((rkind
== CTF_K_ENUM
) && (lkind
== CTF_K_INTEGER
)))
1346 memset (&le
, 0, sizeof (le
));
1347 memset (&re
, 0, sizeof (re
));
1348 return (ctf_type_encoding (lfp
, ltype
, &le
) == 0
1349 && ctf_type_encoding (rfp
, rtype
, &re
) == 0
1350 && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) == 0);
1352 return (ctf_type_compat (lfp
, ctf_type_reference (lfp
, ltype
),
1353 rfp
, ctf_type_reference (rfp
, rtype
)));
1355 return (ctf_array_info (lfp
, ltype
, &la
) == 0
1356 && ctf_array_info (rfp
, rtype
, &ra
) == 0
1357 && la
.ctr_nelems
== ra
.ctr_nelems
1358 && ctf_type_compat (lfp
, la
.ctr_contents
, rfp
, ra
.ctr_contents
)
1359 && ctf_type_compat (lfp
, la
.ctr_index
, rfp
, ra
.ctr_index
));
1362 return (same_names
&& (ctf_type_size (lfp
, ltype
)
1363 == ctf_type_size (rfp
, rtype
)));
1366 int lencoded
, rencoded
;
1367 lencoded
= ctf_type_encoding (lfp
, ltype
, &le
);
1368 rencoded
= ctf_type_encoding (rfp
, rtype
, &re
);
1370 if ((lencoded
!= rencoded
) ||
1371 ((lencoded
== 0) && memcmp (&le
, &re
, sizeof (ctf_encoding_t
)) != 0))
1376 return same_names
; /* No other checks required for these type kinds. */
1378 return 0; /* Should not get here since we did a resolve. */
1382 /* Return the number of members in a STRUCT or UNION, or the number of
1383 enumerators in an ENUM. The count does not include unnamed sub-members. */
1386 ctf_member_count (ctf_dict_t
*fp
, ctf_id_t type
)
1388 ctf_dict_t
*ofp
= fp
;
1389 const ctf_type_t
*tp
;
1392 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1393 return -1; /* errno is set for us. */
1395 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1396 return -1; /* errno is set for us. */
1398 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1400 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
&& kind
!= CTF_K_ENUM
)
1401 return (ctf_set_errno (ofp
, ECTF_NOTSUE
));
1403 return LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1406 /* Return the type and offset for a given member of a STRUCT or UNION. */
1409 ctf_member_info (ctf_dict_t
*fp
, ctf_id_t type
, const char *name
,
1410 ctf_membinfo_t
*mip
)
1412 ctf_dict_t
*ofp
= fp
;
1413 const ctf_type_t
*tp
;
1415 ssize_t size
, increment
;
1418 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1419 return -1; /* errno is set for us. */
1421 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1422 return -1; /* errno is set for us. */
1424 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1425 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1427 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1428 return (ctf_set_errno (ofp
, ECTF_NOTSOU
));
1430 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1432 if (size
< CTF_LSTRUCT_THRESH
)
1434 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1437 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1439 const char *membname
= ctf_strptr (fp
, mp
->ctm_name
);
1441 if (membname
[0] == 0
1442 && (ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_STRUCT
1443 || ctf_type_kind (fp
, mp
->ctm_type
) == CTF_K_UNION
)
1444 && (ctf_member_info (fp
, mp
->ctm_type
, name
, mip
) == 0))
1447 if (strcmp (membname
, name
) == 0)
1449 mip
->ctm_type
= mp
->ctm_type
;
1450 mip
->ctm_offset
= mp
->ctm_offset
;
1457 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1460 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1462 const char *membname
= ctf_strptr (fp
, lmp
->ctlm_name
);
1464 if (membname
[0] == 0
1465 && (ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_STRUCT
1466 || ctf_type_kind (fp
, lmp
->ctlm_type
) == CTF_K_UNION
)
1467 && (ctf_member_info (fp
, lmp
->ctlm_type
, name
, mip
) == 0))
1470 if (strcmp (membname
, name
) == 0)
1472 mip
->ctm_type
= lmp
->ctlm_type
;
1473 mip
->ctm_offset
= (unsigned long) CTF_LMEM_OFFSET (lmp
);
1483 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1484 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1486 if (dmd
->dmd_name
== NULL
1487 && (ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_STRUCT
1488 || ctf_type_kind (fp
, dmd
->dmd_type
) == CTF_K_UNION
)
1489 && (ctf_member_info (fp
, dmd
->dmd_type
, name
, mip
) == 0))
1492 if (dmd
->dmd_name
!= NULL
1493 && strcmp (dmd
->dmd_name
, name
) == 0)
1495 mip
->ctm_type
= dmd
->dmd_type
;
1496 mip
->ctm_offset
= dmd
->dmd_offset
;
1502 return (ctf_set_errno (ofp
, ECTF_NOMEMBNAM
));
1505 /* Return the array type, index, and size information for the specified ARRAY. */
1508 ctf_array_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_arinfo_t
*arp
)
1510 ctf_dict_t
*ofp
= fp
;
1511 const ctf_type_t
*tp
;
1512 const ctf_array_t
*ap
;
1513 const ctf_dtdef_t
*dtd
;
1516 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1517 return -1; /* errno is set for us. */
1519 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ARRAY
)
1520 return (ctf_set_errno (ofp
, ECTF_NOTARRAY
));
1522 if ((dtd
= ctf_dynamic_type (ofp
, type
)) != NULL
)
1523 ap
= (const ctf_array_t
*) dtd
->dtd_vlen
;
1526 ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1527 ap
= (const ctf_array_t
*) ((uintptr_t) tp
+ increment
);
1529 arp
->ctr_contents
= ap
->cta_contents
;
1530 arp
->ctr_index
= ap
->cta_index
;
1531 arp
->ctr_nelems
= ap
->cta_nelems
;
1536 /* Convert the specified value to the corresponding enum tag name, if a
1537 matching name can be found. Otherwise NULL is returned. */
1540 ctf_enum_name (ctf_dict_t
*fp
, ctf_id_t type
, int value
)
1542 ctf_dict_t
*ofp
= fp
;
1543 const ctf_type_t
*tp
;
1544 const ctf_enum_t
*ep
;
1545 const ctf_dtdef_t
*dtd
;
1549 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1550 return NULL
; /* errno is set for us. */
1552 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1553 return NULL
; /* errno is set for us. */
1555 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1557 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1561 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1563 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1565 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1567 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1569 if (ep
->cte_value
== value
)
1570 return (ctf_strptr (fp
, ep
->cte_name
));
1577 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1578 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1580 if (dmd
->dmd_value
== value
)
1581 return dmd
->dmd_name
;
1585 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1589 /* Convert the specified enum tag name to the corresponding value, if a
1590 matching name can be found. Otherwise CTF_ERR is returned. */
1593 ctf_enum_value (ctf_dict_t
* fp
, ctf_id_t type
, const char *name
, int *valp
)
1595 ctf_dict_t
*ofp
= fp
;
1596 const ctf_type_t
*tp
;
1597 const ctf_enum_t
*ep
;
1598 const ctf_dtdef_t
*dtd
;
1602 if ((type
= ctf_type_resolve_unsliced (fp
, type
)) == CTF_ERR
)
1603 return -1; /* errno is set for us. */
1605 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1606 return -1; /* errno is set for us. */
1608 if (LCTF_INFO_KIND (fp
, tp
->ctt_info
) != CTF_K_ENUM
)
1610 (void) ctf_set_errno (ofp
, ECTF_NOTENUM
);
1614 (void) ctf_get_ctt_size (fp
, tp
, NULL
, &increment
);
1616 ep
= (const ctf_enum_t
*) ((uintptr_t) tp
+ increment
);
1618 if ((dtd
= ctf_dynamic_type (ofp
, type
)) == NULL
)
1620 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, ep
++)
1622 if (strcmp (ctf_strptr (fp
, ep
->cte_name
), name
) == 0)
1625 *valp
= ep
->cte_value
;
1634 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1635 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1637 if (strcmp (dmd
->dmd_name
, name
) == 0)
1640 *valp
= dmd
->dmd_value
;
1646 (void) ctf_set_errno (ofp
, ECTF_NOENUMNAM
);
1650 /* Given a type ID relating to a function type, return info on return types and
1651 arg counts for that function. */
1654 ctf_func_type_info (ctf_dict_t
*fp
, ctf_id_t type
, ctf_funcinfo_t
*fip
)
1656 const ctf_type_t
*tp
;
1658 const uint32_t *args
;
1659 const ctf_dtdef_t
*dtd
;
1660 ssize_t size
, increment
;
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
);
1669 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1671 if (kind
!= CTF_K_FUNCTION
)
1672 return (ctf_set_errno (fp
, ECTF_NOTFUNC
));
1674 fip
->ctc_return
= tp
->ctt_type
;
1676 fip
->ctc_argc
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
);
1678 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1679 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1681 args
= (uint32_t *) dtd
->dtd_vlen
;
1683 if (fip
->ctc_argc
!= 0 && args
[fip
->ctc_argc
- 1] == 0)
1685 fip
->ctc_flags
|= CTF_FUNC_VARARG
;
1692 /* Given a type ID relating to a function type, return the arguments for the
1696 ctf_func_type_args (ctf_dict_t
*fp
, ctf_id_t type
, uint32_t argc
, ctf_id_t
*argv
)
1698 const ctf_type_t
*tp
;
1699 const uint32_t *args
;
1700 const ctf_dtdef_t
*dtd
;
1701 ssize_t size
, increment
;
1704 if (ctf_func_type_info (fp
, type
, &f
) < 0)
1705 return -1; /* errno is set for us. */
1707 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1708 return -1; /* errno is set for us. */
1710 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1711 return -1; /* errno is set for us. */
1713 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1715 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1716 args
= (uint32_t *) ((uintptr_t) tp
+ increment
);
1718 args
= (uint32_t *) dtd
->dtd_vlen
;
1720 for (argc
= MIN (argc
, f
.ctc_argc
); argc
!= 0; argc
--)
1726 /* Recursively visit the members of any type. This function is used as the
1727 engine for ctf_type_visit, below. We resolve the input type, recursively
1728 invoke ourself for each type member if the type is a struct or union, and
1729 then invoke the callback function on the current type. If any callback
1730 returns non-zero, we abort and percolate the error code back up to the top. */
1733 ctf_type_rvisit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
,
1734 void *arg
, const char *name
, unsigned long offset
, int depth
)
1736 ctf_id_t otype
= type
;
1737 const ctf_type_t
*tp
;
1738 const ctf_dtdef_t
*dtd
;
1739 ssize_t size
, increment
;
1743 if ((type
= ctf_type_resolve (fp
, type
)) == CTF_ERR
)
1744 return -1; /* errno is set for us. */
1746 if ((tp
= ctf_lookup_by_id (&fp
, type
)) == NULL
)
1747 return -1; /* errno is set for us. */
1749 if ((rc
= func (name
, otype
, offset
, depth
, arg
)) != 0)
1752 kind
= LCTF_INFO_KIND (fp
, tp
->ctt_info
);
1754 if (kind
!= CTF_K_STRUCT
&& kind
!= CTF_K_UNION
)
1757 (void) ctf_get_ctt_size (fp
, tp
, &size
, &increment
);
1759 if ((dtd
= ctf_dynamic_type (fp
, type
)) == NULL
)
1761 if (size
< CTF_LSTRUCT_THRESH
)
1763 const ctf_member_t
*mp
= (const ctf_member_t
*) ((uintptr_t) tp
+
1766 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, mp
++)
1768 if ((rc
= ctf_type_rvisit (fp
, mp
->ctm_type
,
1769 func
, arg
, ctf_strptr (fp
,
1771 offset
+ mp
->ctm_offset
,
1778 const ctf_lmember_t
*lmp
= (const ctf_lmember_t
*) ((uintptr_t) tp
+
1781 for (n
= LCTF_INFO_VLEN (fp
, tp
->ctt_info
); n
!= 0; n
--, lmp
++)
1783 if ((rc
= ctf_type_rvisit (fp
, lmp
->ctlm_type
,
1784 func
, arg
, ctf_strptr (fp
,
1786 offset
+ (unsigned long) CTF_LMEM_OFFSET (lmp
),
1796 for (dmd
= ctf_list_next (&dtd
->dtd_u
.dtu_members
);
1797 dmd
!= NULL
; dmd
= ctf_list_next (dmd
))
1799 if ((rc
= ctf_type_rvisit (fp
, dmd
->dmd_type
, func
, arg
,
1800 dmd
->dmd_name
, dmd
->dmd_offset
,
1809 /* Recursively visit the members of any type. We pass the name, member
1810 type, and offset of each member to the specified callback function. */
1812 ctf_type_visit (ctf_dict_t
*fp
, ctf_id_t type
, ctf_visit_f
*func
, void *arg
)
1814 return (ctf_type_rvisit (fp
, type
, func
, arg
, "", 0, 0));