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