libctf: eliminate dtd_u, part 3: functions
[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
49 while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
50 {
51 int rc;
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_next_t *i = NULL;
259 const char *name;
260 int val;
261
262 while ((name = ctf_enum_next (fp, type, &i, &val)) != NULL)
263 {
264 int rc;
265 if ((rc = func (name, val, arg)) != 0)
266 {
267 ctf_next_destroy (i);
268 return rc;
269 }
270 }
271 if (ctf_errno (fp) != ECTF_NEXT_END)
272 return -1; /* errno is set for us. */
273
274 return 0;
275 }
276
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. */
280
281 const char *
282 ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
283 int *val)
284 {
285 ctf_dict_t *ofp = fp;
286 uint32_t kind;
287 const char *name;
288 ctf_next_t *i = *it;
289
290 if (!i)
291 {
292 const ctf_type_t *tp;
293 ctf_dtdef_t *dtd;
294
295 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
296 return NULL; /* errno is set for us. */
297
298 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
299 return NULL; /* errno is set for us. */
300
301 if ((i = ctf_next_create ()) == NULL)
302 {
303 ctf_set_errno (ofp, ENOMEM);
304 return NULL;
305 }
306 i->cu.ctn_fp = ofp;
307
308 (void) ctf_get_ctt_size (fp, tp, NULL,
309 &i->ctn_increment);
310 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
311
312 if (kind != CTF_K_ENUM)
313 {
314 ctf_next_destroy (i);
315 ctf_set_errno (ofp, ECTF_NOTENUM);
316 return NULL;
317 }
318
319 dtd = ctf_dynamic_type (fp, type);
320 i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
321
322 /* We depend below on the RDWR state indicating whether the DTD-related
323 fields or the DMD-related fields have been initialized. */
324
325 assert ((dtd && (fp->ctf_flags & LCTF_RDWR))
326 || (!dtd && (!(fp->ctf_flags & LCTF_RDWR))));
327
328 if (dtd == NULL)
329 {
330 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
331
332 i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
333 i->ctn_increment);
334 }
335 else
336 i->u.ctn_dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
337
338 *it = i;
339 }
340
341 if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
342 {
343 ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
344 return NULL;
345 }
346
347 if (ofp != i->cu.ctn_fp)
348 {
349 ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
350 return NULL;
351 }
352
353 /* Resolve to the native dict of this type. */
354 if ((fp = ctf_get_dict (ofp, type)) == NULL)
355 {
356 ctf_set_errno (ofp, ECTF_NOPARENT);
357 return NULL;
358 }
359
360 if (!(fp->ctf_flags & LCTF_RDWR))
361 {
362 if (i->ctn_n == 0)
363 goto end_iter;
364
365 name = ctf_strptr (fp, i->u.ctn_en->cte_name);
366 if (val)
367 *val = i->u.ctn_en->cte_value;
368 i->u.ctn_en++;
369 i->ctn_n--;
370 }
371 else
372 {
373 if (i->u.ctn_dmd == NULL)
374 goto end_iter;
375
376 name = i->u.ctn_dmd->dmd_name;
377 if (val)
378 *val = i->u.ctn_dmd->dmd_value;
379 i->u.ctn_dmd = ctf_list_next (i->u.ctn_dmd);
380 }
381
382 return name;
383
384 end_iter:
385 ctf_next_destroy (i);
386 *it = NULL;
387 ctf_set_errno (ofp, ECTF_NEXT_END);
388 return NULL;
389 }
390
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.
393
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. */
397
398 int
399 ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
400 {
401 ctf_next_t *i = NULL;
402 ctf_id_t type;
403
404 while ((type = ctf_type_next (fp, &i, NULL, 0)) != CTF_ERR)
405 {
406 int rc;
407 if ((rc = func (type, arg)) != 0)
408 {
409 ctf_next_destroy (i);
410 return rc;
411 }
412 }
413 if (ctf_errno (fp) != ECTF_NEXT_END)
414 return -1; /* errno is set for us. */
415
416 return 0;
417 }
418
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.
421
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. */
425
426 int
427 ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
428 {
429 ctf_next_t *i = NULL;
430 ctf_id_t type;
431 int flag;
432
433 while ((type = ctf_type_next (fp, &i, &flag, 1)) != CTF_ERR)
434 {
435 int rc;
436 if ((rc = func (type, flag, arg)) != 0)
437 {
438 ctf_next_destroy (i);
439 return rc;
440 }
441 }
442 if (ctf_errno (fp) != ECTF_NEXT_END)
443 return -1; /* errno is set for us. */
444
445 return 0;
446 }
447
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.
451
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. */
455
456 ctf_id_t
457 ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
458 {
459 ctf_next_t *i = *it;
460
461 if (!i)
462 {
463 if ((i = ctf_next_create ()) == NULL)
464 return ctf_set_errno (fp, ENOMEM);
465
466 i->cu.ctn_fp = fp;
467 i->ctn_type = 1;
468 i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
469 *it = i;
470 }
471
472 if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
473 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
474
475 if (fp != i->cu.ctn_fp)
476 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
477
478 while (i->ctn_type <= fp->ctf_typemax)
479 {
480 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);
481
482 if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
483 {
484 i->ctn_type++;
485 continue;
486 }
487
488 if (flag)
489 *flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
490 return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
491 }
492 ctf_next_destroy (i);
493 *it = NULL;
494 return ctf_set_errno (fp, ECTF_NEXT_END);
495 }
496
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. */
499
500 int
501 ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
502 {
503 ctf_next_t *i = NULL;
504 ctf_id_t type;
505 const char *name;
506
507 while ((type = ctf_variable_next (fp, &i, &name)) != CTF_ERR)
508 {
509 int rc;
510 if ((rc = func (name, type, arg)) != 0)
511 {
512 ctf_next_destroy (i);
513 return rc;
514 }
515 }
516 if (ctf_errno (fp) != ECTF_NEXT_END)
517 return -1; /* errno is set for us. */
518
519 return 0;
520 }
521
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. */
525
526 ctf_id_t
527 ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
528 {
529 ctf_next_t *i = *it;
530
531 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
532 return (ctf_set_errno (fp, ECTF_NOPARENT));
533
534 if (!i)
535 {
536 if ((i = ctf_next_create ()) == NULL)
537 return ctf_set_errno (fp, ENOMEM);
538
539 i->cu.ctn_fp = fp;
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);
543 *it = i;
544 }
545
546 if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
547 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
548
549 if (fp != i->cu.ctn_fp)
550 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
551
552 if (!(fp->ctf_flags & LCTF_RDWR))
553 {
554 if (i->ctn_n >= fp->ctf_nvars)
555 goto end_iter;
556
557 *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
558 return fp->ctf_vars[i->ctn_n++].ctv_type;
559 }
560 else
561 {
562 ctf_id_t id;
563
564 if (i->u.ctn_dvd == NULL)
565 goto end_iter;
566
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);
570 return id;
571 }
572
573 end_iter:
574 ctf_next_destroy (i);
575 *it = NULL;
576 return ctf_set_errno (fp, ECTF_NEXT_END);
577 }
578
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.
584
585 Does not drill down through slices to their contained type.
586
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. */
589
590 ctf_id_t
591 ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
592 {
593 ctf_id_t prev = type, otype = type;
594 ctf_dict_t *ofp = fp;
595 const ctf_type_t *tp;
596
597 if (type == 0)
598 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
599
600 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
601 {
602 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
603 {
604 case CTF_K_TYPEDEF:
605 case CTF_K_VOLATILE:
606 case CTF_K_CONST:
607 case CTF_K_RESTRICT:
608 if (tp->ctt_type == type || tp->ctt_type == otype
609 || tp->ctt_type == prev)
610 {
611 ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
612 otype);
613 return (ctf_set_errno (ofp, ECTF_CORRUPT));
614 }
615 prev = type;
616 type = tp->ctt_type;
617 break;
618 default:
619 return type;
620 }
621 if (type == 0)
622 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
623 }
624
625 return CTF_ERR; /* errno is set for us. */
626 }
627
628 /* Like ctf_type_resolve(), but traverse down through slices to their contained
629 type. */
630
631 ctf_id_t
632 ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
633 {
634 const ctf_type_t *tp;
635
636 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
637 return -1;
638
639 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
640 return CTF_ERR; /* errno is set for us. */
641
642 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
643 return ctf_type_reference (fp, type);
644 return type;
645 }
646
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. */
650 ctf_dict_t *
651 ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
652 {
653 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
654 return fp->ctf_parent;
655
656 return fp;
657 }
658
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. */
661
662 ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
663 {
664 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
665 }
666
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
669 identifier. */
670
671 ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
672 {
673 ctf_id_t id;
674
675 if (fp->ctf_flags & LCTF_RDWR)
676 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
677 else
678 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
679 return id;
680 }
681
682 /* Lookup the given type ID and return its name as a new dynamically-allocated
683 string. */
684
685 char *
686 ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
687 {
688 ctf_decl_t cd;
689 ctf_decl_node_t *cdp;
690 ctf_decl_prec_t prec, lp, rp;
691 int ptr, arr;
692 uint32_t k;
693 char *buf;
694
695 if (fp == NULL && type == CTF_ERR)
696 return NULL; /* Simplify caller code by permitting CTF_ERR. */
697
698 ctf_decl_init (&cd);
699 ctf_decl_push (&cd, fp, type);
700
701 if (cd.cd_err != 0)
702 {
703 ctf_decl_fini (&cd);
704 ctf_set_errno (fp, cd.cd_err);
705 return NULL;
706 }
707
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 (*[])(). */
713
714 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
715 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
716
717 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
718 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
719
720 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
721
722 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
723 {
724 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
725 cdp != NULL; cdp = ctf_list_next (cdp))
726 {
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);
730
731 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
732 ctf_decl_sprintf (&cd, " ");
733
734 if (lp == prec)
735 {
736 ctf_decl_sprintf (&cd, "(");
737 lp = -1;
738 }
739
740 switch (cdp->cd_kind)
741 {
742 case CTF_K_INTEGER:
743 case CTF_K_FLOAT:
744 case CTF_K_TYPEDEF:
745 /* Integers, floats, and typedefs must always be named types. */
746
747 if (name[0] == '\0')
748 {
749 ctf_set_errno (fp, ECTF_CORRUPT);
750 ctf_decl_fini (&cd);
751 return NULL;
752 }
753
754 ctf_decl_sprintf (&cd, "%s", name);
755 break;
756 case CTF_K_POINTER:
757 ctf_decl_sprintf (&cd, "*");
758 break;
759 case CTF_K_ARRAY:
760 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
761 break;
762 case CTF_K_FUNCTION:
763 {
764 size_t i;
765 ctf_funcinfo_t fi;
766 ctf_id_t *argv = NULL;
767
768 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
769 goto err; /* errno is set for us. */
770
771 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
772 {
773 ctf_set_errno (rfp, errno);
774 goto err;
775 }
776
777 if (ctf_func_type_args (rfp, cdp->cd_type,
778 fi.ctc_argc, argv) < 0)
779 goto err; /* errno is set for us. */
780
781 ctf_decl_sprintf (&cd, "(*) (");
782 for (i = 0; i < fi.ctc_argc; i++)
783 {
784 char *arg = ctf_type_aname (rfp, argv[i]);
785
786 if (arg == NULL)
787 goto err; /* errno is set for us. */
788 ctf_decl_sprintf (&cd, "%s", arg);
789 free (arg);
790
791 if ((i < fi.ctc_argc - 1)
792 || (fi.ctc_flags & CTF_FUNC_VARARG))
793 ctf_decl_sprintf (&cd, ", ");
794 }
795
796 if (fi.ctc_flags & CTF_FUNC_VARARG)
797 ctf_decl_sprintf (&cd, "...");
798 ctf_decl_sprintf (&cd, ")");
799
800 free (argv);
801 break;
802
803 err:
804 free (argv);
805 ctf_decl_fini (&cd);
806 return NULL;
807 }
808 break;
809 case CTF_K_STRUCT:
810 ctf_decl_sprintf (&cd, "struct %s", name);
811 break;
812 case CTF_K_UNION:
813 ctf_decl_sprintf (&cd, "union %s", name);
814 break;
815 case CTF_K_ENUM:
816 ctf_decl_sprintf (&cd, "enum %s", name);
817 break;
818 case CTF_K_FORWARD:
819 {
820 switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
821 {
822 case CTF_K_STRUCT:
823 ctf_decl_sprintf (&cd, "struct %s", name);
824 break;
825 case CTF_K_UNION:
826 ctf_decl_sprintf (&cd, "union %s", name);
827 break;
828 case CTF_K_ENUM:
829 ctf_decl_sprintf (&cd, "enum %s", name);
830 break;
831 default:
832 ctf_set_errno (fp, ECTF_CORRUPT);
833 ctf_decl_fini (&cd);
834 return NULL;
835 }
836 break;
837 }
838 case CTF_K_VOLATILE:
839 ctf_decl_sprintf (&cd, "volatile");
840 break;
841 case CTF_K_CONST:
842 ctf_decl_sprintf (&cd, "const");
843 break;
844 case CTF_K_RESTRICT:
845 ctf_decl_sprintf (&cd, "restrict");
846 break;
847 }
848
849 k = cdp->cd_kind;
850 }
851
852 if (rp == prec)
853 ctf_decl_sprintf (&cd, ")");
854 }
855
856 if (cd.cd_enomem)
857 (void) ctf_set_errno (fp, ENOMEM);
858
859 buf = ctf_decl_buf (&cd);
860
861 ctf_decl_fini (&cd);
862 return buf;
863 }
864
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. */
867
868 ssize_t
869 ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
870 {
871 char *str = ctf_type_aname (fp, type);
872 size_t slen;
873
874 if (str == NULL)
875 return CTF_ERR; /* errno is set for us. */
876
877 slen = strlen (str);
878 snprintf (buf, len, "%s", str);
879 free (str);
880
881 if (slen >= len)
882 (void) ctf_set_errno (fp, ECTF_NAMELEN);
883
884 return slen;
885 }
886
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. */
889
890 char *
891 ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
892 {
893 ssize_t rv = ctf_type_lname (fp, type, buf, len);
894 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
895 }
896
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.
899
900 The only decoration is that a NULL return always means an error: nameless
901 types return a null string. */
902
903 const char *
904 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
905 {
906 const ctf_type_t *tp;
907
908 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
909 return NULL; /* errno is set for us. */
910
911 if (tp->ctt_name == 0)
912 return "";
913
914 return ctf_strraw (fp, tp->ctt_name);
915 }
916
917 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
918 new dynamically-allocated string. */
919
920 char *
921 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
922 {
923 const char *name = ctf_type_name_raw (fp, type);
924
925 if (name != NULL)
926 return strdup (name);
927
928 return NULL;
929 }
930
931 /* Resolve the type down to a base type node, and then return the size
932 of the type storage in bytes. */
933
934 ssize_t
935 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
936 {
937 ctf_dict_t *ofp = fp;
938 const ctf_type_t *tp;
939 ssize_t size;
940 ctf_arinfo_t ar;
941
942 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
943 return -1; /* errno is set for us. */
944
945 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
946 return -1; /* errno is set for us. */
947
948 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
949 {
950 case CTF_K_POINTER:
951 return fp->ctf_dmodel->ctd_pointer;
952
953 case CTF_K_FUNCTION:
954 return 0; /* Function size is only known by symtab. */
955
956 case CTF_K_ENUM:
957 return fp->ctf_dmodel->ctd_int;
958
959 case CTF_K_ARRAY:
960 /* ctf_add_array() does not directly encode the element size, but
961 requires the user to multiply to determine the element size.
962
963 If ctf_get_ctt_size() returns nonzero, then use the recorded
964 size instead. */
965
966 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
967 return size;
968
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. */
972
973 return size * ar.ctr_nelems;
974
975 case CTF_K_FORWARD:
976 /* Forwards do not have a meaningful size. */
977 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
978
979 default: /* including slices of enums, etc */
980 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
981 }
982 }
983
984 /* Resolve the type down to a base type node, and then return the alignment
985 needed for the type storage in bytes.
986
987 XXX may need arch-dependent attention. */
988
989 ssize_t
990 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
991 {
992 const ctf_type_t *tp;
993 ctf_dict_t *ofp = fp;
994 int kind;
995
996 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
997 return -1; /* errno is set for us. */
998
999 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1000 return -1; /* errno is set for us. */
1001
1002 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1003 switch (kind)
1004 {
1005 case CTF_K_POINTER:
1006 case CTF_K_FUNCTION:
1007 return fp->ctf_dmodel->ctd_pointer;
1008
1009 case CTF_K_ARRAY:
1010 {
1011 ctf_arinfo_t r;
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));
1015 }
1016
1017 case CTF_K_STRUCT:
1018 case CTF_K_UNION:
1019 {
1020 size_t align = 0;
1021 ctf_dtdef_t *dtd;
1022
1023 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1024 {
1025 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1026 ssize_t size, increment;
1027 const void *vmp;
1028
1029 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1030 vmp = (unsigned char *) tp + increment;
1031
1032 if (kind == CTF_K_STRUCT)
1033 n = MIN (n, 1); /* Only use first member for structs. */
1034
1035 if (size < CTF_LSTRUCT_THRESH)
1036 {
1037 const ctf_member_t *mp = vmp;
1038 for (; n != 0; n--, mp++)
1039 {
1040 ssize_t am = ctf_type_align (ofp, mp->ctm_type);
1041 align = MAX (align, (size_t) am);
1042 }
1043 }
1044 else
1045 {
1046 const ctf_lmember_t *lmp = vmp;
1047 for (; n != 0; n--, lmp++)
1048 {
1049 ssize_t am = ctf_type_align (ofp, lmp->ctlm_type);
1050 align = MAX (align, (size_t) am);
1051 }
1052 }
1053 }
1054 else
1055 {
1056 ctf_dmdef_t *dmd;
1057
1058 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1059 dmd != NULL; dmd = ctf_list_next (dmd))
1060 {
1061 ssize_t am = ctf_type_align (ofp, dmd->dmd_type);
1062 align = MAX (align, (size_t) am);
1063 if (kind == CTF_K_STRUCT)
1064 break;
1065 }
1066 }
1067
1068 return align;
1069 }
1070
1071 case CTF_K_ENUM:
1072 return fp->ctf_dmodel->ctd_int;
1073
1074 case CTF_K_FORWARD:
1075 /* Forwards do not have a meaningful alignment. */
1076 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1077
1078 default: /* including slices of enums, etc */
1079 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1080 }
1081 }
1082
1083 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1084
1085 int
1086 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1087 {
1088 const ctf_type_t *tp;
1089
1090 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1091 return -1; /* errno is set for us. */
1092
1093 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1094 }
1095
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. */
1098
1099 int
1100 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1101 {
1102 int kind;
1103
1104 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1105 return -1;
1106
1107 if (kind == CTF_K_SLICE)
1108 {
1109 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1110 return -1;
1111 kind = ctf_type_kind_unsliced (fp, type);
1112 }
1113
1114 return kind;
1115 }
1116
1117 /* Return the kind of this type, except, for forwards, return the kind of thing
1118 this is a forward to. */
1119 int
1120 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1121 {
1122 int kind;
1123 const ctf_type_t *tp;
1124
1125 if ((kind = ctf_type_kind (fp, type)) < 0)
1126 return -1; /* errno is set for us. */
1127
1128 if (kind != CTF_K_FORWARD)
1129 return kind;
1130
1131 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1132 return -1; /* errno is set for us. */
1133
1134 return tp->ctt_type;
1135 }
1136
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. */
1139
1140 ctf_id_t
1141 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1142 {
1143 ctf_dict_t *ofp = fp;
1144 const ctf_type_t *tp;
1145
1146 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1147 return CTF_ERR; /* errno is set for us. */
1148
1149 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1150 {
1151 case CTF_K_POINTER:
1152 case CTF_K_TYPEDEF:
1153 case CTF_K_VOLATILE:
1154 case CTF_K_CONST:
1155 case CTF_K_RESTRICT:
1156 return tp->ctt_type;
1157 /* Slices store their type in an unusual place. */
1158 case CTF_K_SLICE:
1159 {
1160 ctf_dtdef_t *dtd;
1161 const ctf_slice_t *sp;
1162
1163 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1164 {
1165 ssize_t increment;
1166
1167 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1168 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1169 }
1170 else
1171 sp = (const ctf_slice_t *) dtd->dtd_vlen;
1172
1173 return sp->cts_type;
1174 }
1175 default:
1176 return (ctf_set_errno (ofp, ECTF_NOTREF));
1177 }
1178 }
1179
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.
1185
1186 XXX what about parent dicts? */
1187
1188 ctf_id_t
1189 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1190 {
1191 ctf_dict_t *ofp = fp;
1192 ctf_id_t ntype;
1193
1194 if (ctf_lookup_by_id (&fp, type) == NULL)
1195 return CTF_ERR; /* errno is set for us. */
1196
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)));
1199
1200 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1201 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1202
1203 if (ctf_lookup_by_id (&fp, type) == NULL)
1204 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1205
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)));
1208
1209 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1210 }
1211
1212 /* Return the encoding for the specified INTEGER or FLOAT. */
1213
1214 int
1215 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1216 {
1217 ctf_dict_t *ofp = fp;
1218 ctf_dtdef_t *dtd;
1219 const ctf_type_t *tp;
1220 ssize_t increment;
1221 const unsigned char *vlen;
1222 uint32_t data;
1223
1224 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1225 return -1; /* errno is set for us. */
1226
1227 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1228 vlen = dtd->dtd_vlen;
1229 else
1230 {
1231 ctf_get_ctt_size (fp, tp, NULL, &increment);
1232 vlen = (const unsigned char *) ((uintptr_t) tp + increment);
1233 }
1234
1235 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1236 {
1237 case CTF_K_INTEGER:
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);
1242 break;
1243 case CTF_K_FLOAT:
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);
1248 break;
1249 case CTF_K_SLICE:
1250 {
1251 const ctf_slice_t *slice;
1252 ctf_encoding_t underlying_en;
1253 ctf_id_t underlying;
1254
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. */
1259
1260 ep->cte_format = underlying_en.cte_format;
1261 ep->cte_offset = slice->cts_offset;
1262 ep->cte_bits = slice->cts_bits;
1263 break;
1264 }
1265 default:
1266 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1267 }
1268
1269 return 0;
1270 }
1271
1272 int
1273 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1274 ctf_id_t rtype)
1275 {
1276 int rval;
1277
1278 if (ltype < rtype)
1279 rval = -1;
1280 else if (ltype > rtype)
1281 rval = 1;
1282 else
1283 rval = 0;
1284
1285 if (lfp == rfp)
1286 return rval;
1287
1288 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1289 lfp = lfp->ctf_parent;
1290
1291 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1292 rfp = rfp->ctf_parent;
1293
1294 if (lfp < rfp)
1295 return -1;
1296
1297 if (lfp > rfp)
1298 return 1;
1299
1300 return rval;
1301 }
1302
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. */
1308
1309 int
1310 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1311 ctf_dict_t *rfp, ctf_id_t rtype)
1312 {
1313 const ctf_type_t *ltp, *rtp;
1314 ctf_encoding_t le, re;
1315 ctf_arinfo_t la, ra;
1316 uint32_t lkind, rkind;
1317 int same_names = 0;
1318
1319 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1320 return 1;
1321
1322 ltype = ctf_type_resolve (lfp, ltype);
1323 lkind = ctf_type_kind (lfp, ltype);
1324
1325 rtype = ctf_type_resolve (rfp, rtype);
1326 rkind = ctf_type_kind (rfp, rtype);
1327
1328 ltp = ctf_lookup_by_id (&lfp, ltype);
1329 rtp = ctf_lookup_by_id (&rfp, rtype);
1330
1331 if (ltp != NULL && rtp != NULL)
1332 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1333 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1334
1335 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1336 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1337 return 1;
1338
1339 if (lkind != rkind)
1340 return 0;
1341
1342 switch (lkind)
1343 {
1344 case CTF_K_INTEGER:
1345 case CTF_K_FLOAT:
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);
1351 case CTF_K_POINTER:
1352 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1353 rfp, ctf_type_reference (rfp, rtype)));
1354 case CTF_K_ARRAY:
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));
1360 case CTF_K_STRUCT:
1361 case CTF_K_UNION:
1362 return (same_names && (ctf_type_size (lfp, ltype)
1363 == ctf_type_size (rfp, rtype)));
1364 case CTF_K_ENUM:
1365 {
1366 int lencoded, rencoded;
1367 lencoded = ctf_type_encoding (lfp, ltype, &le);
1368 rencoded = ctf_type_encoding (rfp, rtype, &re);
1369
1370 if ((lencoded != rencoded) ||
1371 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1372 return 0;
1373 }
1374 /* FALLTHRU */
1375 case CTF_K_FORWARD:
1376 return same_names; /* No other checks required for these type kinds. */
1377 default:
1378 return 0; /* Should not get here since we did a resolve. */
1379 }
1380 }
1381
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. */
1384
1385 int
1386 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1387 {
1388 ctf_dict_t *ofp = fp;
1389 const ctf_type_t *tp;
1390 uint32_t kind;
1391
1392 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1393 return -1; /* errno is set for us. */
1394
1395 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1396 return -1; /* errno is set for us. */
1397
1398 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1399
1400 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1401 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1402
1403 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1404 }
1405
1406 /* Return the type and offset for a given member of a STRUCT or UNION. */
1407
1408 int
1409 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1410 ctf_membinfo_t *mip)
1411 {
1412 ctf_dict_t *ofp = fp;
1413 const ctf_type_t *tp;
1414 ctf_dtdef_t *dtd;
1415 ssize_t size, increment;
1416 uint32_t kind, n;
1417
1418 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1419 return -1; /* errno is set for us. */
1420
1421 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1422 return -1; /* errno is set for us. */
1423
1424 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1425 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1426
1427 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1428 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1429
1430 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1431 {
1432 if (size < CTF_LSTRUCT_THRESH)
1433 {
1434 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1435 increment);
1436
1437 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1438 {
1439 const char *membname = ctf_strptr (fp, mp->ctm_name);
1440
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))
1445 return 0;
1446
1447 if (strcmp (membname, name) == 0)
1448 {
1449 mip->ctm_type = mp->ctm_type;
1450 mip->ctm_offset = mp->ctm_offset;
1451 return 0;
1452 }
1453 }
1454 }
1455 else
1456 {
1457 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1458 increment);
1459
1460 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1461 {
1462 const char *membname = ctf_strptr (fp, lmp->ctlm_name);
1463
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))
1468 return 0;
1469
1470 if (strcmp (membname, name) == 0)
1471 {
1472 mip->ctm_type = lmp->ctlm_type;
1473 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1474 return 0;
1475 }
1476 }
1477 }
1478 }
1479 else
1480 {
1481 ctf_dmdef_t *dmd;
1482
1483 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1484 dmd != NULL; dmd = ctf_list_next (dmd))
1485 {
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))
1490 return 0;
1491
1492 if (dmd->dmd_name != NULL
1493 && strcmp (dmd->dmd_name, name) == 0)
1494 {
1495 mip->ctm_type = dmd->dmd_type;
1496 mip->ctm_offset = dmd->dmd_offset;
1497 return 0;
1498 }
1499 }
1500 }
1501
1502 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1503 }
1504
1505 /* Return the array type, index, and size information for the specified ARRAY. */
1506
1507 int
1508 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1509 {
1510 ctf_dict_t *ofp = fp;
1511 const ctf_type_t *tp;
1512 const ctf_array_t *ap;
1513 const ctf_dtdef_t *dtd;
1514 ssize_t increment;
1515
1516 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1517 return -1; /* errno is set for us. */
1518
1519 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1520 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1521
1522 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1523 ap = (const ctf_array_t *) dtd->dtd_vlen;
1524 else
1525 {
1526 ctf_get_ctt_size (fp, tp, NULL, &increment);
1527 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1528 }
1529 arp->ctr_contents = ap->cta_contents;
1530 arp->ctr_index = ap->cta_index;
1531 arp->ctr_nelems = ap->cta_nelems;
1532
1533 return 0;
1534 }
1535
1536 /* Convert the specified value to the corresponding enum tag name, if a
1537 matching name can be found. Otherwise NULL is returned. */
1538
1539 const char *
1540 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1541 {
1542 ctf_dict_t *ofp = fp;
1543 const ctf_type_t *tp;
1544 const ctf_enum_t *ep;
1545 const ctf_dtdef_t *dtd;
1546 ssize_t increment;
1547 uint32_t n;
1548
1549 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1550 return NULL; /* errno is set for us. */
1551
1552 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1553 return NULL; /* errno is set for us. */
1554
1555 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1556 {
1557 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1558 return NULL;
1559 }
1560
1561 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1562
1563 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1564 {
1565 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1566
1567 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1568 {
1569 if (ep->cte_value == value)
1570 return (ctf_strptr (fp, ep->cte_name));
1571 }
1572 }
1573 else
1574 {
1575 ctf_dmdef_t *dmd;
1576
1577 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1578 dmd != NULL; dmd = ctf_list_next (dmd))
1579 {
1580 if (dmd->dmd_value == value)
1581 return dmd->dmd_name;
1582 }
1583 }
1584
1585 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1586 return NULL;
1587 }
1588
1589 /* Convert the specified enum tag name to the corresponding value, if a
1590 matching name can be found. Otherwise CTF_ERR is returned. */
1591
1592 int
1593 ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
1594 {
1595 ctf_dict_t *ofp = fp;
1596 const ctf_type_t *tp;
1597 const ctf_enum_t *ep;
1598 const ctf_dtdef_t *dtd;
1599 ssize_t increment;
1600 uint32_t n;
1601
1602 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1603 return -1; /* errno is set for us. */
1604
1605 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1606 return -1; /* errno is set for us. */
1607
1608 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1609 {
1610 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1611 return -1;
1612 }
1613
1614 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1615
1616 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1617
1618 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1619 {
1620 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1621 {
1622 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1623 {
1624 if (valp != NULL)
1625 *valp = ep->cte_value;
1626 return 0;
1627 }
1628 }
1629 }
1630 else
1631 {
1632 ctf_dmdef_t *dmd;
1633
1634 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1635 dmd != NULL; dmd = ctf_list_next (dmd))
1636 {
1637 if (strcmp (dmd->dmd_name, name) == 0)
1638 {
1639 if (valp != NULL)
1640 *valp = dmd->dmd_value;
1641 return 0;
1642 }
1643 }
1644 }
1645
1646 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1647 return -1;
1648 }
1649
1650 /* Given a type ID relating to a function type, return info on return types and
1651 arg counts for that function. */
1652
1653 int
1654 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1655 {
1656 const ctf_type_t *tp;
1657 uint32_t kind;
1658 const uint32_t *args;
1659 const ctf_dtdef_t *dtd;
1660 ssize_t size, increment;
1661
1662 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1663 return -1; /* errno is set for us. */
1664
1665 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1666 return -1; /* errno is set for us. */
1667
1668 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1669 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1670
1671 if (kind != CTF_K_FUNCTION)
1672 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1673
1674 fip->ctc_return = tp->ctt_type;
1675 fip->ctc_flags = 0;
1676 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1677
1678 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1679 args = (uint32_t *) ((uintptr_t) tp + increment);
1680 else
1681 args = (uint32_t *) dtd->dtd_vlen;
1682
1683 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1684 {
1685 fip->ctc_flags |= CTF_FUNC_VARARG;
1686 fip->ctc_argc--;
1687 }
1688
1689 return 0;
1690 }
1691
1692 /* Given a type ID relating to a function type, return the arguments for the
1693 function. */
1694
1695 int
1696 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1697 {
1698 const ctf_type_t *tp;
1699 const uint32_t *args;
1700 const ctf_dtdef_t *dtd;
1701 ssize_t size, increment;
1702 ctf_funcinfo_t f;
1703
1704 if (ctf_func_type_info (fp, type, &f) < 0)
1705 return -1; /* errno is set for us. */
1706
1707 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1708 return -1; /* errno is set for us. */
1709
1710 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1711 return -1; /* errno is set for us. */
1712
1713 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1714
1715 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1716 args = (uint32_t *) ((uintptr_t) tp + increment);
1717 else
1718 args = (uint32_t *) dtd->dtd_vlen;
1719
1720 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1721 *argv++ = *args++;
1722
1723 return 0;
1724 }
1725
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. */
1731
1732 static int
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)
1735 {
1736 ctf_id_t otype = type;
1737 const ctf_type_t *tp;
1738 const ctf_dtdef_t *dtd;
1739 ssize_t size, increment;
1740 uint32_t kind, n;
1741 int rc;
1742
1743 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1744 return -1; /* errno is set for us. */
1745
1746 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1747 return -1; /* errno is set for us. */
1748
1749 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1750 return rc;
1751
1752 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1753
1754 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1755 return 0;
1756
1757 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1758
1759 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1760 {
1761 if (size < CTF_LSTRUCT_THRESH)
1762 {
1763 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1764 increment);
1765
1766 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1767 {
1768 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1769 func, arg, ctf_strptr (fp,
1770 mp->ctm_name),
1771 offset + mp->ctm_offset,
1772 depth + 1)) != 0)
1773 return rc;
1774 }
1775 }
1776 else
1777 {
1778 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1779 increment);
1780
1781 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1782 {
1783 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1784 func, arg, ctf_strptr (fp,
1785 lmp->ctlm_name),
1786 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1787 depth + 1)) != 0)
1788 return rc;
1789 }
1790 }
1791 }
1792 else
1793 {
1794 ctf_dmdef_t *dmd;
1795
1796 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1797 dmd != NULL; dmd = ctf_list_next (dmd))
1798 {
1799 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1800 dmd->dmd_name, dmd->dmd_offset,
1801 depth + 1)) != 0)
1802 return rc;
1803 }
1804 }
1805
1806 return 0;
1807 }
1808
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. */
1811 int
1812 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1813 {
1814 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1815 }