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