libctf, include: support unnamed structure members better
[binutils-gdb.git] / libctf / ctf-types.c
1 /* Type handling functions.
2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
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
9 version.
10
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.
15
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/>. */
19
20 #include <ctf-impl.h>
21 #include <assert.h>
22 #include <string.h>
23
24 /* Determine whether a type is a parent or a child. */
25
26 int
27 ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
28 {
29 return (LCTF_TYPE_ISPARENT (fp, id));
30 }
31
32 int
33 ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id)
34 {
35 return (LCTF_TYPE_ISCHILD (fp, id));
36 }
37
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. */
40
41 int
42 ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
43 {
44 ctf_next_t *i = NULL;
45 ssize_t offset;
46 const char *name;
47 ctf_id_t membtype;
48 int rc;
49
50 while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
51 {
52 if ((rc = func (name, membtype, offset, arg)) != 0)
53 {
54 ctf_next_destroy (i);
55 return rc;
56 }
57 }
58 if (ctf_errno (fp) != ECTF_NEXT_END)
59 return -1; /* errno is set for us. */
60
61 return 0;
62 }
63
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. */
67
68 ssize_t
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)
71 {
72 ctf_dict_t *ofp = fp;
73 uint32_t kind;
74 ssize_t offset;
75 ctf_next_t *i = *it;
76
77 if (!i)
78 {
79 const ctf_type_t *tp;
80 ctf_dtdef_t *dtd;
81 ssize_t increment;
82
83 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
84 return -1; /* errno is set for us. */
85
86 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
87 return -1; /* errno is set for us. */
88
89 if ((i = ctf_next_create ()) == NULL)
90 return ctf_set_errno (ofp, ENOMEM);
91 i->cu.ctn_fp = ofp;
92
93 (void) ctf_get_ctt_size (fp, tp, &i->ctn_size, &increment);
94 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
95
96 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
97 {
98 ctf_next_destroy (i);
99 return (ctf_set_errno (ofp, ECTF_NOTSOU));
100 }
101
102 dtd = ctf_dynamic_type (fp, type);
103 i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
104
105 /* We depend below on the RDWR state indicating whether the DTD-related
106 fields or the DMD-related fields have been initialized. */
107
108 assert ((dtd && (fp->ctf_flags & LCTF_RDWR))
109 || (!dtd && (!(fp->ctf_flags & LCTF_RDWR))));
110
111 if (dtd == NULL)
112 {
113 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
114
115 if (i->ctn_size < CTF_LSTRUCT_THRESH)
116 i->u.ctn_mp = (const ctf_member_t *) ((uintptr_t) tp + increment);
117 else
118 i->u.ctn_lmp = (const ctf_lmember_t *) ((uintptr_t) tp + increment);
119 }
120 else
121 i->u.ctn_dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
122
123 *it = i;
124 }
125
126 if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
127 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));
128
129 if (ofp != i->cu.ctn_fp)
130 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));
131
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));
135
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. */
140
141 retry:
142 if (!i->ctn_type)
143 {
144 if (!(fp->ctf_flags & LCTF_RDWR))
145 {
146 if (i->ctn_n == 0)
147 goto end_iter;
148
149 if (i->ctn_size < CTF_LSTRUCT_THRESH)
150 {
151 const char *membname = ctf_strptr (fp, i->u.ctn_mp->ctm_name);
152
153 if (name)
154 *name = membname;
155 if (membtype)
156 *membtype = i->u.ctn_mp->ctm_type;
157 offset = i->u.ctn_mp->ctm_offset;
158
159 if (membname[0] == 0
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;
163
164 i->u.ctn_mp++;
165 }
166 else
167 {
168 const char *membname = ctf_strptr (fp, i->u.ctn_lmp->ctlm_name);
169
170 if (name)
171 *name = membname;
172 if (membtype)
173 *membtype = i->u.ctn_lmp->ctlm_type;
174 offset = (unsigned long) CTF_LMEM_OFFSET (i->u.ctn_lmp);
175
176 if (membname[0] == 0
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;
180
181 i->u.ctn_lmp++;
182 }
183 i->ctn_n--;
184 }
185 else
186 {
187 if (i->u.ctn_dmd == NULL)
188 goto end_iter;
189 /* The dmd contains a NULL for unnamed dynamic members. Don't inflict
190 this on our callers. */
191 if (name)
192 {
193 if (i->u.ctn_dmd->dmd_name)
194 *name = i->u.ctn_dmd->dmd_name;
195 else
196 *name = "";
197 }
198 if (membtype)
199 *membtype = i->u.ctn_dmd->dmd_type;
200 offset = i->u.ctn_dmd->dmd_offset;
201
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;
206
207 i->u.ctn_dmd = ctf_list_next (i->u.ctn_dmd);
208 }
209
210 /* The callers might want automatic recursive sub-struct traversal. */
211 if (!(flags & CTF_MN_RECURSE))
212 i->ctn_type = 0;
213
214 /* Sub-struct traversal starting? Take note of the offset of this member,
215 for later boosting of sub-struct members' offsets. */
216 if (i->ctn_type)
217 i->ctn_increment = offset;
218 }
219 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
220 else
221 {
222 ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name,
223 membtype, flags);
224
225 if (ret >= 0)
226 return ret + i->ctn_increment;
227
228 if (ctf_errno (fp) != ECTF_NEXT_END)
229 {
230 ctf_next_destroy (i);
231 *it = NULL;
232 i->ctn_type = 0;
233 return ret; /* errno is set for us. */
234 }
235
236 if (!ctf_assert (fp, (i->ctn_next == NULL)))
237 return -1; /* errno is set for us. */
238
239 i->ctn_type = 0;
240 /* This sub-struct has ended: on to the next real member. */
241 goto retry;
242 }
243
244 return offset;
245
246 end_iter:
247 ctf_next_destroy (i);
248 *it = NULL;
249 return ctf_set_errno (ofp, ECTF_NEXT_END);
250 }
251
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. */
254
255 int
256 ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
257 {
258 ctf_dict_t *ofp = fp;
259 const ctf_type_t *tp;
260 const ctf_enum_t *ep;
261 ctf_dtdef_t *dtd;
262 ssize_t increment;
263 uint32_t n;
264 int rc;
265
266 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
267 return -1; /* errno is set for us. */
268
269 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
270 return -1; /* errno is set for us. */
271
272 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
273 return (ctf_set_errno (ofp, ECTF_NOTENUM));
274
275 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
276
277 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
278 {
279 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
280
281 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
282 {
283 const char *name = ctf_strptr (fp, ep->cte_name);
284 if ((rc = func (name, ep->cte_value, arg)) != 0)
285 return rc;
286 }
287 }
288 else
289 {
290 ctf_dmdef_t *dmd;
291
292 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
293 dmd != NULL; dmd = ctf_list_next (dmd))
294 {
295 if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
296 return rc;
297 }
298 }
299
300 return 0;
301 }
302
303 /* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
304 NULL at end of iteration or error, and optionally passing back the
305 enumerand's integer VALue. */
306
307 const char *
308 ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
309 int *val)
310 {
311 ctf_dict_t *ofp = fp;
312 uint32_t kind;
313 const char *name;
314 ctf_next_t *i = *it;
315
316 if (!i)
317 {
318 const ctf_type_t *tp;
319 ctf_dtdef_t *dtd;
320
321 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
322 return NULL; /* errno is set for us. */
323
324 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
325 return NULL; /* errno is set for us. */
326
327 if ((i = ctf_next_create ()) == NULL)
328 {
329 ctf_set_errno (ofp, ENOMEM);
330 return NULL;
331 }
332 i->cu.ctn_fp = ofp;
333
334 (void) ctf_get_ctt_size (fp, tp, NULL,
335 &i->ctn_increment);
336 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
337
338 if (kind != CTF_K_ENUM)
339 {
340 ctf_next_destroy (i);
341 ctf_set_errno (ofp, ECTF_NOTENUM);
342 return NULL;
343 }
344
345 dtd = ctf_dynamic_type (fp, type);
346 i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
347
348 /* We depend below on the RDWR state indicating whether the DTD-related
349 fields or the DMD-related fields have been initialized. */
350
351 assert ((dtd && (fp->ctf_flags & LCTF_RDWR))
352 || (!dtd && (!(fp->ctf_flags & LCTF_RDWR))));
353
354 if (dtd == NULL)
355 {
356 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
357
358 i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
359 i->ctn_increment);
360 }
361 else
362 i->u.ctn_dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
363
364 *it = i;
365 }
366
367 if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
368 {
369 ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
370 return NULL;
371 }
372
373 if (ofp != i->cu.ctn_fp)
374 {
375 ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
376 return NULL;
377 }
378
379 /* Resolve to the native dict of this type. */
380 if ((fp = ctf_get_dict (ofp, type)) == NULL)
381 {
382 ctf_set_errno (ofp, ECTF_NOPARENT);
383 return NULL;
384 }
385
386 if (!(fp->ctf_flags & LCTF_RDWR))
387 {
388 if (i->ctn_n == 0)
389 goto end_iter;
390
391 name = ctf_strptr (fp, i->u.ctn_en->cte_name);
392 if (val)
393 *val = i->u.ctn_en->cte_value;
394 i->u.ctn_en++;
395 i->ctn_n--;
396 }
397 else
398 {
399 if (i->u.ctn_dmd == NULL)
400 goto end_iter;
401
402 name = i->u.ctn_dmd->dmd_name;
403 if (val)
404 *val = i->u.ctn_dmd->dmd_value;
405 i->u.ctn_dmd = ctf_list_next (i->u.ctn_dmd);
406 }
407
408 return name;
409
410 end_iter:
411 ctf_next_destroy (i);
412 *it = NULL;
413 ctf_set_errno (ofp, ECTF_NEXT_END);
414 return NULL;
415 }
416
417 /* Iterate over every root (user-visible) type in the given CTF dict.
418 We pass the type ID of each type to the specified callback function.
419
420 Does not traverse parent types: you have to do that explicitly. This is by
421 design, to avoid traversing them more than once if traversing many children
422 of a single parent. */
423
424 int
425 ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
426 {
427 ctf_id_t id, max = fp->ctf_typemax;
428 int rc, child = (fp->ctf_flags & LCTF_CHILD);
429
430 for (id = 1; id <= max; id++)
431 {
432 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
433 if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
434 && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
435 return rc;
436 }
437
438 return 0;
439 }
440
441 /* Iterate over every type in the given CTF dict, user-visible or not.
442 We pass the type ID of each type to the specified callback function.
443
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. */
447
448 int
449 ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
450 {
451 ctf_id_t id, max = fp->ctf_typemax;
452 int rc, child = (fp->ctf_flags & LCTF_CHILD);
453
454 for (id = 1; id <= max; id++)
455 {
456 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
457 if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
458 LCTF_INFO_ISROOT(fp, tp->ctt_info)
459 ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
460 return rc;
461 }
462
463 return 0;
464 }
465
466 /* Iterate over every type in the given CTF dict, optionally including
467 non-user-visible types, returning each type ID and hidden flag in turn.
468 Returns CTF_ERR on end of iteration or error.
469
470 Does not traverse parent types: you have to do that explicitly. This is by
471 design, to avoid traversing them more than once if traversing many children
472 of a single parent. */
473
474 ctf_id_t
475 ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
476 {
477 ctf_next_t *i = *it;
478
479 if (!i)
480 {
481 if ((i = ctf_next_create ()) == NULL)
482 return ctf_set_errno (fp, ENOMEM);
483
484 i->cu.ctn_fp = fp;
485 i->ctn_type = 1;
486 i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
487 *it = i;
488 }
489
490 if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
491 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
492
493 if (fp != i->cu.ctn_fp)
494 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
495
496 while (i->ctn_type <= fp->ctf_typemax)
497 {
498 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);
499
500 if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
501 {
502 i->ctn_type++;
503 continue;
504 }
505
506 if (flag)
507 *flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
508 return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
509 }
510 ctf_next_destroy (i);
511 *it = NULL;
512 return ctf_set_errno (fp, ECTF_NEXT_END);
513 }
514
515 /* Iterate over every variable in the given CTF dict, in arbitrary order.
516 We pass the name of each variable to the specified callback function. */
517
518 int
519 ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
520 {
521 int rc;
522
523 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
524 return (ctf_set_errno (fp, ECTF_NOPARENT));
525
526 if (!(fp->ctf_flags & LCTF_RDWR))
527 {
528 unsigned long i;
529 for (i = 0; i < fp->ctf_nvars; i++)
530 if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
531 fp->ctf_vars[i].ctv_type, arg)) != 0)
532 return rc;
533 }
534 else
535 {
536 ctf_dvdef_t *dvd;
537
538 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
539 dvd = ctf_list_next (dvd))
540 {
541 if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
542 return rc;
543 }
544 }
545
546 return 0;
547 }
548
549 /* Iterate over every variable in the given CTF dict, in arbitrary order,
550 returning the name and type of each variable in turn. The name argument is
551 not optional. Returns CTF_ERR on end of iteration or error. */
552
553 ctf_id_t
554 ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
555 {
556 ctf_next_t *i = *it;
557
558 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
559 return (ctf_set_errno (fp, ECTF_NOPARENT));
560
561 if (!i)
562 {
563 if ((i = ctf_next_create ()) == NULL)
564 return ctf_set_errno (fp, ENOMEM);
565
566 i->cu.ctn_fp = fp;
567 i->ctn_iter_fun = (void (*) (void)) ctf_variable_next;
568 if (fp->ctf_flags & LCTF_RDWR)
569 i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs);
570 *it = i;
571 }
572
573 if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
574 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
575
576 if (fp != i->cu.ctn_fp)
577 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
578
579 if (!(fp->ctf_flags & LCTF_RDWR))
580 {
581 if (i->ctn_n >= fp->ctf_nvars)
582 goto end_iter;
583
584 *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
585 return fp->ctf_vars[i->ctn_n++].ctv_type;
586 }
587 else
588 {
589 ctf_id_t id;
590
591 if (i->u.ctn_dvd == NULL)
592 goto end_iter;
593
594 *name = i->u.ctn_dvd->dvd_name;
595 id = i->u.ctn_dvd->dvd_type;
596 i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd);
597 return id;
598 }
599
600 end_iter:
601 ctf_next_destroy (i);
602 *it = NULL;
603 return ctf_set_errno (fp, ECTF_NEXT_END);
604 }
605
606 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
607 RESTRICT nodes until we reach a "base" type node. This is useful when
608 we want to follow a type ID to a node that has members or a size. To guard
609 against infinite loops, we implement simplified cycle detection and check
610 each link against itself, the previous node, and the topmost node.
611
612 Does not drill down through slices to their contained type.
613
614 Callers of this function must not presume that a type it returns must have a
615 valid ctt_size: forwards do not, and must be separately handled. */
616
617 ctf_id_t
618 ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
619 {
620 ctf_id_t prev = type, otype = type;
621 ctf_dict_t *ofp = fp;
622 const ctf_type_t *tp;
623
624 if (type == 0)
625 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
626
627 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
628 {
629 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
630 {
631 case CTF_K_TYPEDEF:
632 case CTF_K_VOLATILE:
633 case CTF_K_CONST:
634 case CTF_K_RESTRICT:
635 if (tp->ctt_type == type || tp->ctt_type == otype
636 || tp->ctt_type == prev)
637 {
638 ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
639 otype);
640 return (ctf_set_errno (ofp, ECTF_CORRUPT));
641 }
642 prev = type;
643 type = tp->ctt_type;
644 break;
645 default:
646 return type;
647 }
648 if (type == 0)
649 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
650 }
651
652 return CTF_ERR; /* errno is set for us. */
653 }
654
655 /* Like ctf_type_resolve(), but traverse down through slices to their contained
656 type. */
657
658 ctf_id_t
659 ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
660 {
661 const ctf_type_t *tp;
662
663 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
664 return -1;
665
666 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
667 return CTF_ERR; /* errno is set for us. */
668
669 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
670 return ctf_type_reference (fp, type);
671 return type;
672 }
673
674 /* Return the native dict of a given type: if called on a child and the
675 type is in the parent, return the parent. Needed if you plan to access
676 the type directly, without using the API. */
677 ctf_dict_t *
678 ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
679 {
680 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
681 return fp->ctf_parent;
682
683 return fp;
684 }
685
686 /* Look up a name in the given name table, in the appropriate hash given the
687 kind of the identifier. The name is a raw, undecorated identifier. */
688
689 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
690 {
691 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
692 }
693
694 /* Look up a name in the given name table, in the appropriate hash given the
695 readability state of the dictionary. The name is a raw, undecorated
696 identifier. */
697
698 ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
699 {
700 ctf_id_t id;
701
702 if (fp->ctf_flags & LCTF_RDWR)
703 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
704 else
705 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
706 return id;
707 }
708
709 /* Lookup the given type ID and return its name as a new dynamically-allocated
710 string. */
711
712 char *
713 ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
714 {
715 ctf_decl_t cd;
716 ctf_decl_node_t *cdp;
717 ctf_decl_prec_t prec, lp, rp;
718 int ptr, arr;
719 uint32_t k;
720 char *buf;
721
722 if (fp == NULL && type == CTF_ERR)
723 return NULL; /* Simplify caller code by permitting CTF_ERR. */
724
725 ctf_decl_init (&cd);
726 ctf_decl_push (&cd, fp, type);
727
728 if (cd.cd_err != 0)
729 {
730 ctf_decl_fini (&cd);
731 ctf_set_errno (fp, cd.cd_err);
732 return NULL;
733 }
734
735 /* If the type graph's order conflicts with lexical precedence order
736 for pointers or arrays, then we need to surround the declarations at
737 the corresponding lexical precedence with parentheses. This can
738 result in either a parenthesized pointer (*) as in int (*)() or
739 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
740
741 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
742 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
743
744 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
745 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
746
747 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
748
749 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
750 {
751 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
752 cdp != NULL; cdp = ctf_list_next (cdp))
753 {
754 ctf_dict_t *rfp = fp;
755 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
756 const char *name = ctf_strptr (rfp, tp->ctt_name);
757
758 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
759 ctf_decl_sprintf (&cd, " ");
760
761 if (lp == prec)
762 {
763 ctf_decl_sprintf (&cd, "(");
764 lp = -1;
765 }
766
767 switch (cdp->cd_kind)
768 {
769 case CTF_K_INTEGER:
770 case CTF_K_FLOAT:
771 case CTF_K_TYPEDEF:
772 /* Integers, floats, and typedefs must always be named types. */
773
774 if (name[0] == '\0')
775 {
776 ctf_set_errno (fp, ECTF_CORRUPT);
777 ctf_decl_fini (&cd);
778 return NULL;
779 }
780
781 ctf_decl_sprintf (&cd, "%s", name);
782 break;
783 case CTF_K_POINTER:
784 ctf_decl_sprintf (&cd, "*");
785 break;
786 case CTF_K_ARRAY:
787 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
788 break;
789 case CTF_K_FUNCTION:
790 {
791 size_t i;
792 ctf_funcinfo_t fi;
793 ctf_id_t *argv = NULL;
794
795 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
796 goto err; /* errno is set for us. */
797
798 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
799 {
800 ctf_set_errno (rfp, errno);
801 goto err;
802 }
803
804 if (ctf_func_type_args (rfp, cdp->cd_type,
805 fi.ctc_argc, argv) < 0)
806 goto err; /* errno is set for us. */
807
808 ctf_decl_sprintf (&cd, "(*) (");
809 for (i = 0; i < fi.ctc_argc; i++)
810 {
811 char *arg = ctf_type_aname (rfp, argv[i]);
812
813 if (arg == NULL)
814 goto err; /* errno is set for us. */
815 ctf_decl_sprintf (&cd, "%s", arg);
816 free (arg);
817
818 if ((i < fi.ctc_argc - 1)
819 || (fi.ctc_flags & CTF_FUNC_VARARG))
820 ctf_decl_sprintf (&cd, ", ");
821 }
822
823 if (fi.ctc_flags & CTF_FUNC_VARARG)
824 ctf_decl_sprintf (&cd, "...");
825 ctf_decl_sprintf (&cd, ")");
826
827 free (argv);
828 break;
829
830 err:
831 free (argv);
832 ctf_decl_fini (&cd);
833 return NULL;
834 }
835 break;
836 case CTF_K_STRUCT:
837 case CTF_K_FORWARD:
838 ctf_decl_sprintf (&cd, "struct %s", name);
839 break;
840 case CTF_K_UNION:
841 ctf_decl_sprintf (&cd, "union %s", name);
842 break;
843 case CTF_K_ENUM:
844 ctf_decl_sprintf (&cd, "enum %s", name);
845 break;
846 case CTF_K_VOLATILE:
847 ctf_decl_sprintf (&cd, "volatile");
848 break;
849 case CTF_K_CONST:
850 ctf_decl_sprintf (&cd, "const");
851 break;
852 case CTF_K_RESTRICT:
853 ctf_decl_sprintf (&cd, "restrict");
854 break;
855 }
856
857 k = cdp->cd_kind;
858 }
859
860 if (rp == prec)
861 ctf_decl_sprintf (&cd, ")");
862 }
863
864 if (cd.cd_enomem)
865 (void) ctf_set_errno (fp, ENOMEM);
866
867 buf = ctf_decl_buf (&cd);
868
869 ctf_decl_fini (&cd);
870 return buf;
871 }
872
873 /* Lookup the given type ID and print a string name for it into buf. Return
874 the actual number of bytes (not including \0) needed to format the name. */
875
876 ssize_t
877 ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
878 {
879 char *str = ctf_type_aname (fp, type);
880 size_t slen;
881
882 if (str == NULL)
883 return CTF_ERR; /* errno is set for us. */
884
885 slen = strlen (str);
886 snprintf (buf, len, "%s", str);
887 free (str);
888
889 if (slen >= len)
890 (void) ctf_set_errno (fp, ECTF_NAMELEN);
891
892 return slen;
893 }
894
895 /* Lookup the given type ID and print a string name for it into buf. If buf
896 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
897
898 char *
899 ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
900 {
901 ssize_t rv = ctf_type_lname (fp, type, buf, len);
902 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
903 }
904
905 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
906 The name will live as long as its ctf_dict_t does. */
907
908 const char *
909 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
910 {
911 const ctf_type_t *tp;
912
913 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
914 return NULL; /* errno is set for us. */
915
916 return ctf_strraw (fp, tp->ctt_name);
917 }
918
919 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
920 new dynamically-allocated string. */
921
922 char *
923 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
924 {
925 const char *name = ctf_type_name_raw (fp, type);
926
927 if (name != NULL)
928 return strdup (name);
929
930 return NULL;
931 }
932
933 /* Resolve the type down to a base type node, and then return the size
934 of the type storage in bytes. */
935
936 ssize_t
937 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
938 {
939 ctf_dict_t *ofp = fp;
940 const ctf_type_t *tp;
941 ssize_t size;
942 ctf_arinfo_t ar;
943
944 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
945 return -1; /* errno is set for us. */
946
947 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
948 return -1; /* errno is set for us. */
949
950 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
951 {
952 case CTF_K_POINTER:
953 return fp->ctf_dmodel->ctd_pointer;
954
955 case CTF_K_FUNCTION:
956 return 0; /* Function size is only known by symtab. */
957
958 case CTF_K_ENUM:
959 return fp->ctf_dmodel->ctd_int;
960
961 case CTF_K_ARRAY:
962 /* ctf_add_array() does not directly encode the element size, but
963 requires the user to multiply to determine the element size.
964
965 If ctf_get_ctt_size() returns nonzero, then use the recorded
966 size instead. */
967
968 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
969 return size;
970
971 if (ctf_array_info (ofp, type, &ar) < 0
972 || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
973 return -1; /* errno is set for us. */
974
975 return size * ar.ctr_nelems;
976
977 case CTF_K_FORWARD:
978 /* Forwards do not have a meaningful size. */
979 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
980
981 default: /* including slices of enums, etc */
982 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
983 }
984 }
985
986 /* Resolve the type down to a base type node, and then return the alignment
987 needed for the type storage in bytes.
988
989 XXX may need arch-dependent attention. */
990
991 ssize_t
992 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
993 {
994 const ctf_type_t *tp;
995 ctf_dict_t *ofp = fp;
996 int kind;
997
998 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
999 return -1; /* errno is set for us. */
1000
1001 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1002 return -1; /* errno is set for us. */
1003
1004 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1005 switch (kind)
1006 {
1007 case CTF_K_POINTER:
1008 case CTF_K_FUNCTION:
1009 return fp->ctf_dmodel->ctd_pointer;
1010
1011 case CTF_K_ARRAY:
1012 {
1013 ctf_arinfo_t r;
1014 if (ctf_array_info (ofp, type, &r) < 0)
1015 return -1; /* errno is set for us. */
1016 return (ctf_type_align (ofp, r.ctr_contents));
1017 }
1018
1019 case CTF_K_STRUCT:
1020 case CTF_K_UNION:
1021 {
1022 size_t align = 0;
1023 ctf_dtdef_t *dtd;
1024
1025 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1026 {
1027 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1028 ssize_t size, increment;
1029 const void *vmp;
1030
1031 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1032 vmp = (unsigned char *) tp + increment;
1033
1034 if (kind == CTF_K_STRUCT)
1035 n = MIN (n, 1); /* Only use first member for structs. */
1036
1037 if (size < CTF_LSTRUCT_THRESH)
1038 {
1039 const ctf_member_t *mp = vmp;
1040 for (; n != 0; n--, mp++)
1041 {
1042 ssize_t am = ctf_type_align (ofp, mp->ctm_type);
1043 align = MAX (align, (size_t) am);
1044 }
1045 }
1046 else
1047 {
1048 const ctf_lmember_t *lmp = vmp;
1049 for (; n != 0; n--, lmp++)
1050 {
1051 ssize_t am = ctf_type_align (ofp, lmp->ctlm_type);
1052 align = MAX (align, (size_t) am);
1053 }
1054 }
1055 }
1056 else
1057 {
1058 ctf_dmdef_t *dmd;
1059
1060 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1061 dmd != NULL; dmd = ctf_list_next (dmd))
1062 {
1063 ssize_t am = ctf_type_align (ofp, dmd->dmd_type);
1064 align = MAX (align, (size_t) am);
1065 if (kind == CTF_K_STRUCT)
1066 break;
1067 }
1068 }
1069
1070 return align;
1071 }
1072
1073 case CTF_K_ENUM:
1074 return fp->ctf_dmodel->ctd_int;
1075
1076 case CTF_K_FORWARD:
1077 /* Forwards do not have a meaningful alignment. */
1078 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1079
1080 default: /* including slices of enums, etc */
1081 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1082 }
1083 }
1084
1085 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1086
1087 int
1088 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1089 {
1090 const ctf_type_t *tp;
1091
1092 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1093 return -1; /* errno is set for us. */
1094
1095 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1096 }
1097
1098 /* Return the kind (CTF_K_* constant) for the specified type ID.
1099 Slices are considered to be of the same kind as the type sliced. */
1100
1101 int
1102 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1103 {
1104 int kind;
1105
1106 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1107 return -1;
1108
1109 if (kind == CTF_K_SLICE)
1110 {
1111 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1112 return -1;
1113 kind = ctf_type_kind_unsliced (fp, type);
1114 }
1115
1116 return kind;
1117 }
1118
1119 /* Return the kind of this type, except, for forwards, return the kind of thing
1120 this is a forward to. */
1121 int
1122 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1123 {
1124 int kind;
1125 const ctf_type_t *tp;
1126
1127 if ((kind = ctf_type_kind (fp, type)) < 0)
1128 return -1; /* errno is set for us. */
1129
1130 if (kind != CTF_K_FORWARD)
1131 return kind;
1132
1133 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1134 return -1; /* errno is set for us. */
1135
1136 return tp->ctt_type;
1137 }
1138
1139 /* If the type is one that directly references another type (such as POINTER),
1140 then return the ID of the type to which it refers. */
1141
1142 ctf_id_t
1143 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1144 {
1145 ctf_dict_t *ofp = fp;
1146 const ctf_type_t *tp;
1147
1148 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1149 return CTF_ERR; /* errno is set for us. */
1150
1151 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1152 {
1153 case CTF_K_POINTER:
1154 case CTF_K_TYPEDEF:
1155 case CTF_K_VOLATILE:
1156 case CTF_K_CONST:
1157 case CTF_K_RESTRICT:
1158 return tp->ctt_type;
1159 /* Slices store their type in an unusual place. */
1160 case CTF_K_SLICE:
1161 {
1162 ctf_dtdef_t *dtd;
1163 const ctf_slice_t *sp;
1164
1165 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1166 {
1167 ssize_t increment;
1168
1169 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1170 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1171 }
1172 else
1173 sp = &dtd->dtd_u.dtu_slice;
1174
1175 return sp->cts_type;
1176 }
1177 default:
1178 return (ctf_set_errno (ofp, ECTF_NOTREF));
1179 }
1180 }
1181
1182 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1183 pointer to the given type, see if we can compute a pointer to the type
1184 resulting from resolving the type down to its base type and use that
1185 instead. This helps with cases where the CTF data includes "struct foo *"
1186 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1187
1188 XXX what about parent dicts? */
1189
1190 ctf_id_t
1191 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1192 {
1193 ctf_dict_t *ofp = fp;
1194 ctf_id_t ntype;
1195
1196 if (ctf_lookup_by_id (&fp, type) == NULL)
1197 return CTF_ERR; /* errno is set for us. */
1198
1199 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1200 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1201
1202 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1203 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1204
1205 if (ctf_lookup_by_id (&fp, type) == NULL)
1206 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1207
1208 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1209 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1210
1211 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1212 }
1213
1214 /* Return the encoding for the specified INTEGER or FLOAT. */
1215
1216 int
1217 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1218 {
1219 ctf_dict_t *ofp = fp;
1220 ctf_dtdef_t *dtd;
1221 const ctf_type_t *tp;
1222 ssize_t increment;
1223 uint32_t data;
1224
1225 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1226 return -1; /* errno is set for us. */
1227
1228 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1229 {
1230 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1231 {
1232 case CTF_K_INTEGER:
1233 case CTF_K_FLOAT:
1234 *ep = dtd->dtd_u.dtu_enc;
1235 break;
1236 case CTF_K_SLICE:
1237 {
1238 const ctf_slice_t *slice;
1239 ctf_encoding_t underlying_en;
1240 ctf_id_t underlying;
1241
1242 slice = &dtd->dtd_u.dtu_slice;
1243 underlying = ctf_type_resolve (fp, slice->cts_type);
1244 data = ctf_type_encoding (fp, underlying, &underlying_en);
1245
1246 ep->cte_format = underlying_en.cte_format;
1247 ep->cte_offset = slice->cts_offset;
1248 ep->cte_bits = slice->cts_bits;
1249 break;
1250 }
1251 default:
1252 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1253 }
1254 return 0;
1255 }
1256
1257 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1258
1259 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1260 {
1261 case CTF_K_INTEGER:
1262 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1263 ep->cte_format = CTF_INT_ENCODING (data);
1264 ep->cte_offset = CTF_INT_OFFSET (data);
1265 ep->cte_bits = CTF_INT_BITS (data);
1266 break;
1267 case CTF_K_FLOAT:
1268 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1269 ep->cte_format = CTF_FP_ENCODING (data);
1270 ep->cte_offset = CTF_FP_OFFSET (data);
1271 ep->cte_bits = CTF_FP_BITS (data);
1272 break;
1273 case CTF_K_SLICE:
1274 {
1275 const ctf_slice_t *slice;
1276 ctf_encoding_t underlying_en;
1277 ctf_id_t underlying;
1278
1279 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
1280 underlying = ctf_type_resolve (fp, slice->cts_type);
1281 data = ctf_type_encoding (fp, underlying, &underlying_en);
1282
1283 ep->cte_format = underlying_en.cte_format;
1284 ep->cte_offset = slice->cts_offset;
1285 ep->cte_bits = slice->cts_bits;
1286 break;
1287 }
1288 default:
1289 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1290 }
1291
1292 return 0;
1293 }
1294
1295 int
1296 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1297 ctf_id_t rtype)
1298 {
1299 int rval;
1300
1301 if (ltype < rtype)
1302 rval = -1;
1303 else if (ltype > rtype)
1304 rval = 1;
1305 else
1306 rval = 0;
1307
1308 if (lfp == rfp)
1309 return rval;
1310
1311 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1312 lfp = lfp->ctf_parent;
1313
1314 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1315 rfp = rfp->ctf_parent;
1316
1317 if (lfp < rfp)
1318 return -1;
1319
1320 if (lfp > rfp)
1321 return 1;
1322
1323 return rval;
1324 }
1325
1326 /* Return a boolean value indicating if two types are compatible. This function
1327 returns true if the two types are the same, or if they (or their ultimate
1328 base type) have the same encoding properties, or (for structs / unions /
1329 enums / forward declarations) if they have the same name and (for structs /
1330 unions) member count. */
1331
1332 int
1333 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1334 ctf_dict_t *rfp, ctf_id_t rtype)
1335 {
1336 const ctf_type_t *ltp, *rtp;
1337 ctf_encoding_t le, re;
1338 ctf_arinfo_t la, ra;
1339 uint32_t lkind, rkind;
1340 int same_names = 0;
1341
1342 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1343 return 1;
1344
1345 ltype = ctf_type_resolve (lfp, ltype);
1346 lkind = ctf_type_kind (lfp, ltype);
1347
1348 rtype = ctf_type_resolve (rfp, rtype);
1349 rkind = ctf_type_kind (rfp, rtype);
1350
1351 ltp = ctf_lookup_by_id (&lfp, ltype);
1352 rtp = ctf_lookup_by_id (&rfp, rtype);
1353
1354 if (ltp != NULL && rtp != NULL)
1355 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1356 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1357
1358 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1359 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1360 return 1;
1361
1362 if (lkind != rkind)
1363 return 0;
1364
1365 switch (lkind)
1366 {
1367 case CTF_K_INTEGER:
1368 case CTF_K_FLOAT:
1369 memset (&le, 0, sizeof (le));
1370 memset (&re, 0, sizeof (re));
1371 return (ctf_type_encoding (lfp, ltype, &le) == 0
1372 && ctf_type_encoding (rfp, rtype, &re) == 0
1373 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1374 case CTF_K_POINTER:
1375 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1376 rfp, ctf_type_reference (rfp, rtype)));
1377 case CTF_K_ARRAY:
1378 return (ctf_array_info (lfp, ltype, &la) == 0
1379 && ctf_array_info (rfp, rtype, &ra) == 0
1380 && la.ctr_nelems == ra.ctr_nelems
1381 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1382 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1383 case CTF_K_STRUCT:
1384 case CTF_K_UNION:
1385 return (same_names && (ctf_type_size (lfp, ltype)
1386 == ctf_type_size (rfp, rtype)));
1387 case CTF_K_ENUM:
1388 {
1389 int lencoded, rencoded;
1390 lencoded = ctf_type_encoding (lfp, ltype, &le);
1391 rencoded = ctf_type_encoding (rfp, rtype, &re);
1392
1393 if ((lencoded != rencoded) ||
1394 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1395 return 0;
1396 }
1397 /* FALLTHRU */
1398 case CTF_K_FORWARD:
1399 return same_names; /* No other checks required for these type kinds. */
1400 default:
1401 return 0; /* Should not get here since we did a resolve. */
1402 }
1403 }
1404
1405 /* Return the number of members in a STRUCT or UNION, or the number of
1406 enumerators in an ENUM. The count does not include unnamed sub-members. */
1407
1408 int
1409 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1410 {
1411 ctf_dict_t *ofp = fp;
1412 const ctf_type_t *tp;
1413 uint32_t kind;
1414
1415 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1416 return -1; /* errno is set for us. */
1417
1418 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1419 return -1; /* errno is set for us. */
1420
1421 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1422
1423 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1424 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1425
1426 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1427 }
1428
1429 /* Return the type and offset for a given member of a STRUCT or UNION. */
1430
1431 int
1432 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1433 ctf_membinfo_t *mip)
1434 {
1435 ctf_dict_t *ofp = fp;
1436 const ctf_type_t *tp;
1437 ctf_dtdef_t *dtd;
1438 ssize_t size, increment;
1439 uint32_t kind, n;
1440
1441 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1442 return -1; /* errno is set for us. */
1443
1444 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1445 return -1; /* errno is set for us. */
1446
1447 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1448 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1449
1450 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1451 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1452
1453 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1454 {
1455 if (size < CTF_LSTRUCT_THRESH)
1456 {
1457 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1458 increment);
1459
1460 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1461 {
1462 const char *membname = ctf_strptr (fp, mp->ctm_name);
1463
1464 if (membname[0] == 0
1465 && (ctf_type_kind (fp, mp->ctm_type) == CTF_K_STRUCT
1466 || ctf_type_kind (fp, mp->ctm_type) == CTF_K_UNION)
1467 && (ctf_member_info (fp, mp->ctm_type, name, mip) == 0))
1468 return 0;
1469
1470 if (strcmp (membname, name) == 0)
1471 {
1472 mip->ctm_type = mp->ctm_type;
1473 mip->ctm_offset = mp->ctm_offset;
1474 return 0;
1475 }
1476 }
1477 }
1478 else
1479 {
1480 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1481 increment);
1482
1483 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1484 {
1485 const char *membname = ctf_strptr (fp, lmp->ctlm_name);
1486
1487 if (membname[0] == 0
1488 && (ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_STRUCT
1489 || ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_UNION)
1490 && (ctf_member_info (fp, lmp->ctlm_type, name, mip) == 0))
1491 return 0;
1492
1493 if (strcmp (membname, name) == 0)
1494 {
1495 mip->ctm_type = lmp->ctlm_type;
1496 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1497 return 0;
1498 }
1499 }
1500 }
1501 }
1502 else
1503 {
1504 ctf_dmdef_t *dmd;
1505
1506 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1507 dmd != NULL; dmd = ctf_list_next (dmd))
1508 {
1509 if (dmd->dmd_name == NULL
1510 && (ctf_type_kind (fp, dmd->dmd_type) == CTF_K_STRUCT
1511 || ctf_type_kind (fp, dmd->dmd_type) == CTF_K_UNION)
1512 && (ctf_member_info (fp, dmd->dmd_type, name, mip) == 0))
1513 return 0;
1514
1515 if (dmd->dmd_name != NULL
1516 && strcmp (dmd->dmd_name, name) == 0)
1517 {
1518 mip->ctm_type = dmd->dmd_type;
1519 mip->ctm_offset = dmd->dmd_offset;
1520 return 0;
1521 }
1522 }
1523 }
1524
1525 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1526 }
1527
1528 /* Return the array type, index, and size information for the specified ARRAY. */
1529
1530 int
1531 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1532 {
1533 ctf_dict_t *ofp = fp;
1534 const ctf_type_t *tp;
1535 const ctf_array_t *ap;
1536 const ctf_dtdef_t *dtd;
1537 ssize_t increment;
1538
1539 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1540 return -1; /* errno is set for us. */
1541
1542 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1543 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1544
1545 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1546 {
1547 *arp = dtd->dtd_u.dtu_arr;
1548 return 0;
1549 }
1550
1551 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1552
1553 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1554 arp->ctr_contents = ap->cta_contents;
1555 arp->ctr_index = ap->cta_index;
1556 arp->ctr_nelems = ap->cta_nelems;
1557
1558 return 0;
1559 }
1560
1561 /* Convert the specified value to the corresponding enum tag name, if a
1562 matching name can be found. Otherwise NULL is returned. */
1563
1564 const char *
1565 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1566 {
1567 ctf_dict_t *ofp = fp;
1568 const ctf_type_t *tp;
1569 const ctf_enum_t *ep;
1570 const ctf_dtdef_t *dtd;
1571 ssize_t increment;
1572 uint32_t n;
1573
1574 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1575 return NULL; /* errno is set for us. */
1576
1577 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1578 return NULL; /* errno is set for us. */
1579
1580 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1581 {
1582 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1583 return NULL;
1584 }
1585
1586 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1587
1588 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1589 {
1590 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1591
1592 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1593 {
1594 if (ep->cte_value == value)
1595 return (ctf_strptr (fp, ep->cte_name));
1596 }
1597 }
1598 else
1599 {
1600 ctf_dmdef_t *dmd;
1601
1602 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1603 dmd != NULL; dmd = ctf_list_next (dmd))
1604 {
1605 if (dmd->dmd_value == value)
1606 return dmd->dmd_name;
1607 }
1608 }
1609
1610 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1611 return NULL;
1612 }
1613
1614 /* Convert the specified enum tag name to the corresponding value, if a
1615 matching name can be found. Otherwise CTF_ERR is returned. */
1616
1617 int
1618 ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
1619 {
1620 ctf_dict_t *ofp = fp;
1621 const ctf_type_t *tp;
1622 const ctf_enum_t *ep;
1623 const ctf_dtdef_t *dtd;
1624 ssize_t increment;
1625 uint32_t n;
1626
1627 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1628 return -1; /* errno is set for us. */
1629
1630 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1631 return -1; /* errno is set for us. */
1632
1633 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1634 {
1635 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1636 return -1;
1637 }
1638
1639 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1640
1641 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1642
1643 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1644 {
1645 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1646 {
1647 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1648 {
1649 if (valp != NULL)
1650 *valp = ep->cte_value;
1651 return 0;
1652 }
1653 }
1654 }
1655 else
1656 {
1657 ctf_dmdef_t *dmd;
1658
1659 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1660 dmd != NULL; dmd = ctf_list_next (dmd))
1661 {
1662 if (strcmp (dmd->dmd_name, name) == 0)
1663 {
1664 if (valp != NULL)
1665 *valp = dmd->dmd_value;
1666 return 0;
1667 }
1668 }
1669 }
1670
1671 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1672 return -1;
1673 }
1674
1675 /* Given a type ID relating to a function type, return info on return types and
1676 arg counts for that function. */
1677
1678 int
1679 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1680 {
1681 const ctf_type_t *tp;
1682 uint32_t kind;
1683 const uint32_t *args;
1684 const ctf_dtdef_t *dtd;
1685 ssize_t size, increment;
1686
1687 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1688 return -1; /* errno is set for us. */
1689
1690 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1691 return -1; /* errno is set for us. */
1692
1693 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1694 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1695
1696 if (kind != CTF_K_FUNCTION)
1697 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1698
1699 fip->ctc_return = tp->ctt_type;
1700 fip->ctc_flags = 0;
1701 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1702
1703 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1704 args = (uint32_t *) ((uintptr_t) tp + increment);
1705 else
1706 args = dtd->dtd_u.dtu_argv;
1707
1708 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1709 {
1710 fip->ctc_flags |= CTF_FUNC_VARARG;
1711 fip->ctc_argc--;
1712 }
1713
1714 return 0;
1715 }
1716
1717 /* Given a type ID relating to a function type, return the arguments for the
1718 function. */
1719
1720 int
1721 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1722 {
1723 const ctf_type_t *tp;
1724 const uint32_t *args;
1725 const ctf_dtdef_t *dtd;
1726 ssize_t size, increment;
1727 ctf_funcinfo_t f;
1728
1729 if (ctf_func_type_info (fp, type, &f) < 0)
1730 return -1; /* errno is set for us. */
1731
1732 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1733 return -1; /* errno is set for us. */
1734
1735 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1736 return -1; /* errno is set for us. */
1737
1738 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1739
1740 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1741 args = (uint32_t *) ((uintptr_t) tp + increment);
1742 else
1743 args = dtd->dtd_u.dtu_argv;
1744
1745 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1746 *argv++ = *args++;
1747
1748 return 0;
1749 }
1750
1751 /* Recursively visit the members of any type. This function is used as the
1752 engine for ctf_type_visit, below. We resolve the input type, recursively
1753 invoke ourself for each type member if the type is a struct or union, and
1754 then invoke the callback function on the current type. If any callback
1755 returns non-zero, we abort and percolate the error code back up to the top. */
1756
1757 static int
1758 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1759 void *arg, const char *name, unsigned long offset, int depth)
1760 {
1761 ctf_id_t otype = type;
1762 const ctf_type_t *tp;
1763 const ctf_dtdef_t *dtd;
1764 ssize_t size, increment;
1765 uint32_t kind, n;
1766 int rc;
1767
1768 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1769 return -1; /* errno is set for us. */
1770
1771 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1772 return -1; /* errno is set for us. */
1773
1774 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1775 return rc;
1776
1777 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1778
1779 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1780 return 0;
1781
1782 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1783
1784 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1785 {
1786 if (size < CTF_LSTRUCT_THRESH)
1787 {
1788 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1789 increment);
1790
1791 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1792 {
1793 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1794 func, arg, ctf_strptr (fp,
1795 mp->ctm_name),
1796 offset + mp->ctm_offset,
1797 depth + 1)) != 0)
1798 return rc;
1799 }
1800 }
1801 else
1802 {
1803 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1804 increment);
1805
1806 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1807 {
1808 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1809 func, arg, ctf_strptr (fp,
1810 lmp->ctlm_name),
1811 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1812 depth + 1)) != 0)
1813 return rc;
1814 }
1815 }
1816 }
1817 else
1818 {
1819 ctf_dmdef_t *dmd;
1820
1821 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1822 dmd != NULL; dmd = ctf_list_next (dmd))
1823 {
1824 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1825 dmd->dmd_name, dmd->dmd_offset,
1826 depth + 1)) != 0)
1827 return rc;
1828 }
1829 }
1830
1831 return 0;
1832 }
1833
1834 /* Recursively visit the members of any type. We pass the name, member
1835 type, and offset of each member to the specified callback function. */
1836 int
1837 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1838 {
1839 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1840 }