libctf: always name nameless types "", never NULL
[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 The only decoration is that a NULL return always means an error: nameless
928 types return a null string. */
929
930 const char *
931 ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
932 {
933 const ctf_type_t *tp;
934
935 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
936 return NULL; /* errno is set for us. */
937
938 if (tp->ctt_name == 0)
939 return "";
940
941 return ctf_strraw (fp, tp->ctt_name);
942 }
943
944 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
945 new dynamically-allocated string. */
946
947 char *
948 ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
949 {
950 const char *name = ctf_type_name_raw (fp, type);
951
952 if (name != NULL)
953 return strdup (name);
954
955 return NULL;
956 }
957
958 /* Resolve the type down to a base type node, and then return the size
959 of the type storage in bytes. */
960
961 ssize_t
962 ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
963 {
964 ctf_dict_t *ofp = fp;
965 const ctf_type_t *tp;
966 ssize_t size;
967 ctf_arinfo_t ar;
968
969 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
970 return -1; /* errno is set for us. */
971
972 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
973 return -1; /* errno is set for us. */
974
975 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
976 {
977 case CTF_K_POINTER:
978 return fp->ctf_dmodel->ctd_pointer;
979
980 case CTF_K_FUNCTION:
981 return 0; /* Function size is only known by symtab. */
982
983 case CTF_K_ENUM:
984 return fp->ctf_dmodel->ctd_int;
985
986 case CTF_K_ARRAY:
987 /* ctf_add_array() does not directly encode the element size, but
988 requires the user to multiply to determine the element size.
989
990 If ctf_get_ctt_size() returns nonzero, then use the recorded
991 size instead. */
992
993 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
994 return size;
995
996 if (ctf_array_info (ofp, type, &ar) < 0
997 || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
998 return -1; /* errno is set for us. */
999
1000 return size * ar.ctr_nelems;
1001
1002 case CTF_K_FORWARD:
1003 /* Forwards do not have a meaningful size. */
1004 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1005
1006 default: /* including slices of enums, etc */
1007 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1008 }
1009 }
1010
1011 /* Resolve the type down to a base type node, and then return the alignment
1012 needed for the type storage in bytes.
1013
1014 XXX may need arch-dependent attention. */
1015
1016 ssize_t
1017 ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
1018 {
1019 const ctf_type_t *tp;
1020 ctf_dict_t *ofp = fp;
1021 int kind;
1022
1023 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1024 return -1; /* errno is set for us. */
1025
1026 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1027 return -1; /* errno is set for us. */
1028
1029 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1030 switch (kind)
1031 {
1032 case CTF_K_POINTER:
1033 case CTF_K_FUNCTION:
1034 return fp->ctf_dmodel->ctd_pointer;
1035
1036 case CTF_K_ARRAY:
1037 {
1038 ctf_arinfo_t r;
1039 if (ctf_array_info (ofp, type, &r) < 0)
1040 return -1; /* errno is set for us. */
1041 return (ctf_type_align (ofp, r.ctr_contents));
1042 }
1043
1044 case CTF_K_STRUCT:
1045 case CTF_K_UNION:
1046 {
1047 size_t align = 0;
1048 ctf_dtdef_t *dtd;
1049
1050 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1051 {
1052 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1053 ssize_t size, increment;
1054 const void *vmp;
1055
1056 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1057 vmp = (unsigned char *) tp + increment;
1058
1059 if (kind == CTF_K_STRUCT)
1060 n = MIN (n, 1); /* Only use first member for structs. */
1061
1062 if (size < CTF_LSTRUCT_THRESH)
1063 {
1064 const ctf_member_t *mp = vmp;
1065 for (; n != 0; n--, mp++)
1066 {
1067 ssize_t am = ctf_type_align (ofp, mp->ctm_type);
1068 align = MAX (align, (size_t) am);
1069 }
1070 }
1071 else
1072 {
1073 const ctf_lmember_t *lmp = vmp;
1074 for (; n != 0; n--, lmp++)
1075 {
1076 ssize_t am = ctf_type_align (ofp, lmp->ctlm_type);
1077 align = MAX (align, (size_t) am);
1078 }
1079 }
1080 }
1081 else
1082 {
1083 ctf_dmdef_t *dmd;
1084
1085 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1086 dmd != NULL; dmd = ctf_list_next (dmd))
1087 {
1088 ssize_t am = ctf_type_align (ofp, dmd->dmd_type);
1089 align = MAX (align, (size_t) am);
1090 if (kind == CTF_K_STRUCT)
1091 break;
1092 }
1093 }
1094
1095 return align;
1096 }
1097
1098 case CTF_K_ENUM:
1099 return fp->ctf_dmodel->ctd_int;
1100
1101 case CTF_K_FORWARD:
1102 /* Forwards do not have a meaningful alignment. */
1103 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1104
1105 default: /* including slices of enums, etc */
1106 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1107 }
1108 }
1109
1110 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1111
1112 int
1113 ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
1114 {
1115 const ctf_type_t *tp;
1116
1117 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1118 return -1; /* errno is set for us. */
1119
1120 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1121 }
1122
1123 /* Return the kind (CTF_K_* constant) for the specified type ID.
1124 Slices are considered to be of the same kind as the type sliced. */
1125
1126 int
1127 ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
1128 {
1129 int kind;
1130
1131 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1132 return -1;
1133
1134 if (kind == CTF_K_SLICE)
1135 {
1136 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1137 return -1;
1138 kind = ctf_type_kind_unsliced (fp, type);
1139 }
1140
1141 return kind;
1142 }
1143
1144 /* Return the kind of this type, except, for forwards, return the kind of thing
1145 this is a forward to. */
1146 int
1147 ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
1148 {
1149 int kind;
1150 const ctf_type_t *tp;
1151
1152 if ((kind = ctf_type_kind (fp, type)) < 0)
1153 return -1; /* errno is set for us. */
1154
1155 if (kind != CTF_K_FORWARD)
1156 return kind;
1157
1158 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1159 return -1; /* errno is set for us. */
1160
1161 return tp->ctt_type;
1162 }
1163
1164 /* If the type is one that directly references another type (such as POINTER),
1165 then return the ID of the type to which it refers. */
1166
1167 ctf_id_t
1168 ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
1169 {
1170 ctf_dict_t *ofp = fp;
1171 const ctf_type_t *tp;
1172
1173 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1174 return CTF_ERR; /* errno is set for us. */
1175
1176 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1177 {
1178 case CTF_K_POINTER:
1179 case CTF_K_TYPEDEF:
1180 case CTF_K_VOLATILE:
1181 case CTF_K_CONST:
1182 case CTF_K_RESTRICT:
1183 return tp->ctt_type;
1184 /* Slices store their type in an unusual place. */
1185 case CTF_K_SLICE:
1186 {
1187 ctf_dtdef_t *dtd;
1188 const ctf_slice_t *sp;
1189
1190 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1191 {
1192 ssize_t increment;
1193
1194 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1195 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1196 }
1197 else
1198 sp = &dtd->dtd_u.dtu_slice;
1199
1200 return sp->cts_type;
1201 }
1202 default:
1203 return (ctf_set_errno (ofp, ECTF_NOTREF));
1204 }
1205 }
1206
1207 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1208 pointer to the given type, see if we can compute a pointer to the type
1209 resulting from resolving the type down to its base type and use that
1210 instead. This helps with cases where the CTF data includes "struct foo *"
1211 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1212
1213 XXX what about parent dicts? */
1214
1215 ctf_id_t
1216 ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
1217 {
1218 ctf_dict_t *ofp = fp;
1219 ctf_id_t ntype;
1220
1221 if (ctf_lookup_by_id (&fp, type) == NULL)
1222 return CTF_ERR; /* errno is set for us. */
1223
1224 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1225 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1226
1227 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1228 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1229
1230 if (ctf_lookup_by_id (&fp, type) == NULL)
1231 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1232
1233 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1234 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1235
1236 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1237 }
1238
1239 /* Return the encoding for the specified INTEGER or FLOAT. */
1240
1241 int
1242 ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1243 {
1244 ctf_dict_t *ofp = fp;
1245 ctf_dtdef_t *dtd;
1246 const ctf_type_t *tp;
1247 ssize_t increment;
1248 uint32_t data;
1249
1250 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1251 return -1; /* errno is set for us. */
1252
1253 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1254 {
1255 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1256 {
1257 case CTF_K_INTEGER:
1258 case CTF_K_FLOAT:
1259 *ep = dtd->dtd_u.dtu_enc;
1260 break;
1261 case CTF_K_SLICE:
1262 {
1263 const ctf_slice_t *slice;
1264 ctf_encoding_t underlying_en;
1265 ctf_id_t underlying;
1266
1267 slice = &dtd->dtd_u.dtu_slice;
1268 underlying = ctf_type_resolve (fp, slice->cts_type);
1269 data = ctf_type_encoding (fp, underlying, &underlying_en);
1270
1271 ep->cte_format = underlying_en.cte_format;
1272 ep->cte_offset = slice->cts_offset;
1273 ep->cte_bits = slice->cts_bits;
1274 break;
1275 }
1276 default:
1277 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1278 }
1279 return 0;
1280 }
1281
1282 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1283
1284 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1285 {
1286 case CTF_K_INTEGER:
1287 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1288 ep->cte_format = CTF_INT_ENCODING (data);
1289 ep->cte_offset = CTF_INT_OFFSET (data);
1290 ep->cte_bits = CTF_INT_BITS (data);
1291 break;
1292 case CTF_K_FLOAT:
1293 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1294 ep->cte_format = CTF_FP_ENCODING (data);
1295 ep->cte_offset = CTF_FP_OFFSET (data);
1296 ep->cte_bits = CTF_FP_BITS (data);
1297 break;
1298 case CTF_K_SLICE:
1299 {
1300 const ctf_slice_t *slice;
1301 ctf_encoding_t underlying_en;
1302 ctf_id_t underlying;
1303
1304 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
1305 underlying = ctf_type_resolve (fp, slice->cts_type);
1306 data = ctf_type_encoding (fp, underlying, &underlying_en);
1307
1308 ep->cte_format = underlying_en.cte_format;
1309 ep->cte_offset = slice->cts_offset;
1310 ep->cte_bits = slice->cts_bits;
1311 break;
1312 }
1313 default:
1314 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1315 }
1316
1317 return 0;
1318 }
1319
1320 int
1321 ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
1322 ctf_id_t rtype)
1323 {
1324 int rval;
1325
1326 if (ltype < rtype)
1327 rval = -1;
1328 else if (ltype > rtype)
1329 rval = 1;
1330 else
1331 rval = 0;
1332
1333 if (lfp == rfp)
1334 return rval;
1335
1336 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1337 lfp = lfp->ctf_parent;
1338
1339 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1340 rfp = rfp->ctf_parent;
1341
1342 if (lfp < rfp)
1343 return -1;
1344
1345 if (lfp > rfp)
1346 return 1;
1347
1348 return rval;
1349 }
1350
1351 /* Return a boolean value indicating if two types are compatible. This function
1352 returns true if the two types are the same, or if they (or their ultimate
1353 base type) have the same encoding properties, or (for structs / unions /
1354 enums / forward declarations) if they have the same name and (for structs /
1355 unions) member count. */
1356
1357 int
1358 ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1359 ctf_dict_t *rfp, ctf_id_t rtype)
1360 {
1361 const ctf_type_t *ltp, *rtp;
1362 ctf_encoding_t le, re;
1363 ctf_arinfo_t la, ra;
1364 uint32_t lkind, rkind;
1365 int same_names = 0;
1366
1367 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1368 return 1;
1369
1370 ltype = ctf_type_resolve (lfp, ltype);
1371 lkind = ctf_type_kind (lfp, ltype);
1372
1373 rtype = ctf_type_resolve (rfp, rtype);
1374 rkind = ctf_type_kind (rfp, rtype);
1375
1376 ltp = ctf_lookup_by_id (&lfp, ltype);
1377 rtp = ctf_lookup_by_id (&rfp, rtype);
1378
1379 if (ltp != NULL && rtp != NULL)
1380 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1381 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1382
1383 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1384 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1385 return 1;
1386
1387 if (lkind != rkind)
1388 return 0;
1389
1390 switch (lkind)
1391 {
1392 case CTF_K_INTEGER:
1393 case CTF_K_FLOAT:
1394 memset (&le, 0, sizeof (le));
1395 memset (&re, 0, sizeof (re));
1396 return (ctf_type_encoding (lfp, ltype, &le) == 0
1397 && ctf_type_encoding (rfp, rtype, &re) == 0
1398 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1399 case CTF_K_POINTER:
1400 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1401 rfp, ctf_type_reference (rfp, rtype)));
1402 case CTF_K_ARRAY:
1403 return (ctf_array_info (lfp, ltype, &la) == 0
1404 && ctf_array_info (rfp, rtype, &ra) == 0
1405 && la.ctr_nelems == ra.ctr_nelems
1406 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1407 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1408 case CTF_K_STRUCT:
1409 case CTF_K_UNION:
1410 return (same_names && (ctf_type_size (lfp, ltype)
1411 == ctf_type_size (rfp, rtype)));
1412 case CTF_K_ENUM:
1413 {
1414 int lencoded, rencoded;
1415 lencoded = ctf_type_encoding (lfp, ltype, &le);
1416 rencoded = ctf_type_encoding (rfp, rtype, &re);
1417
1418 if ((lencoded != rencoded) ||
1419 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1420 return 0;
1421 }
1422 /* FALLTHRU */
1423 case CTF_K_FORWARD:
1424 return same_names; /* No other checks required for these type kinds. */
1425 default:
1426 return 0; /* Should not get here since we did a resolve. */
1427 }
1428 }
1429
1430 /* Return the number of members in a STRUCT or UNION, or the number of
1431 enumerators in an ENUM. The count does not include unnamed sub-members. */
1432
1433 int
1434 ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
1435 {
1436 ctf_dict_t *ofp = fp;
1437 const ctf_type_t *tp;
1438 uint32_t kind;
1439
1440 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1441 return -1; /* errno is set for us. */
1442
1443 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1444 return -1; /* errno is set for us. */
1445
1446 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1447
1448 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1449 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1450
1451 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1452 }
1453
1454 /* Return the type and offset for a given member of a STRUCT or UNION. */
1455
1456 int
1457 ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
1458 ctf_membinfo_t *mip)
1459 {
1460 ctf_dict_t *ofp = fp;
1461 const ctf_type_t *tp;
1462 ctf_dtdef_t *dtd;
1463 ssize_t size, increment;
1464 uint32_t kind, n;
1465
1466 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1467 return -1; /* errno is set for us. */
1468
1469 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1470 return -1; /* errno is set for us. */
1471
1472 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1473 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1474
1475 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1476 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1477
1478 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1479 {
1480 if (size < CTF_LSTRUCT_THRESH)
1481 {
1482 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1483 increment);
1484
1485 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1486 {
1487 const char *membname = ctf_strptr (fp, mp->ctm_name);
1488
1489 if (membname[0] == 0
1490 && (ctf_type_kind (fp, mp->ctm_type) == CTF_K_STRUCT
1491 || ctf_type_kind (fp, mp->ctm_type) == CTF_K_UNION)
1492 && (ctf_member_info (fp, mp->ctm_type, name, mip) == 0))
1493 return 0;
1494
1495 if (strcmp (membname, name) == 0)
1496 {
1497 mip->ctm_type = mp->ctm_type;
1498 mip->ctm_offset = mp->ctm_offset;
1499 return 0;
1500 }
1501 }
1502 }
1503 else
1504 {
1505 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1506 increment);
1507
1508 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1509 {
1510 const char *membname = ctf_strptr (fp, lmp->ctlm_name);
1511
1512 if (membname[0] == 0
1513 && (ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_STRUCT
1514 || ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_UNION)
1515 && (ctf_member_info (fp, lmp->ctlm_type, name, mip) == 0))
1516 return 0;
1517
1518 if (strcmp (membname, name) == 0)
1519 {
1520 mip->ctm_type = lmp->ctlm_type;
1521 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1522 return 0;
1523 }
1524 }
1525 }
1526 }
1527 else
1528 {
1529 ctf_dmdef_t *dmd;
1530
1531 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1532 dmd != NULL; dmd = ctf_list_next (dmd))
1533 {
1534 if (dmd->dmd_name == NULL
1535 && (ctf_type_kind (fp, dmd->dmd_type) == CTF_K_STRUCT
1536 || ctf_type_kind (fp, dmd->dmd_type) == CTF_K_UNION)
1537 && (ctf_member_info (fp, dmd->dmd_type, name, mip) == 0))
1538 return 0;
1539
1540 if (dmd->dmd_name != NULL
1541 && strcmp (dmd->dmd_name, name) == 0)
1542 {
1543 mip->ctm_type = dmd->dmd_type;
1544 mip->ctm_offset = dmd->dmd_offset;
1545 return 0;
1546 }
1547 }
1548 }
1549
1550 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1551 }
1552
1553 /* Return the array type, index, and size information for the specified ARRAY. */
1554
1555 int
1556 ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1557 {
1558 ctf_dict_t *ofp = fp;
1559 const ctf_type_t *tp;
1560 const ctf_array_t *ap;
1561 const ctf_dtdef_t *dtd;
1562 ssize_t increment;
1563
1564 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1565 return -1; /* errno is set for us. */
1566
1567 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1568 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1569
1570 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1571 {
1572 *arp = dtd->dtd_u.dtu_arr;
1573 return 0;
1574 }
1575
1576 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1577
1578 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1579 arp->ctr_contents = ap->cta_contents;
1580 arp->ctr_index = ap->cta_index;
1581 arp->ctr_nelems = ap->cta_nelems;
1582
1583 return 0;
1584 }
1585
1586 /* Convert the specified value to the corresponding enum tag name, if a
1587 matching name can be found. Otherwise NULL is returned. */
1588
1589 const char *
1590 ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
1591 {
1592 ctf_dict_t *ofp = fp;
1593 const ctf_type_t *tp;
1594 const ctf_enum_t *ep;
1595 const ctf_dtdef_t *dtd;
1596 ssize_t increment;
1597 uint32_t n;
1598
1599 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1600 return NULL; /* errno is set for us. */
1601
1602 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1603 return NULL; /* errno is set for us. */
1604
1605 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1606 {
1607 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1608 return NULL;
1609 }
1610
1611 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1612
1613 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1614 {
1615 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1616
1617 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1618 {
1619 if (ep->cte_value == value)
1620 return (ctf_strptr (fp, ep->cte_name));
1621 }
1622 }
1623 else
1624 {
1625 ctf_dmdef_t *dmd;
1626
1627 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1628 dmd != NULL; dmd = ctf_list_next (dmd))
1629 {
1630 if (dmd->dmd_value == value)
1631 return dmd->dmd_name;
1632 }
1633 }
1634
1635 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1636 return NULL;
1637 }
1638
1639 /* Convert the specified enum tag name to the corresponding value, if a
1640 matching name can be found. Otherwise CTF_ERR is returned. */
1641
1642 int
1643 ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
1644 {
1645 ctf_dict_t *ofp = fp;
1646 const ctf_type_t *tp;
1647 const ctf_enum_t *ep;
1648 const ctf_dtdef_t *dtd;
1649 ssize_t increment;
1650 uint32_t n;
1651
1652 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1653 return -1; /* errno is set for us. */
1654
1655 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1656 return -1; /* errno is set for us. */
1657
1658 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1659 {
1660 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1661 return -1;
1662 }
1663
1664 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1665
1666 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1667
1668 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1669 {
1670 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1671 {
1672 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1673 {
1674 if (valp != NULL)
1675 *valp = ep->cte_value;
1676 return 0;
1677 }
1678 }
1679 }
1680 else
1681 {
1682 ctf_dmdef_t *dmd;
1683
1684 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1685 dmd != NULL; dmd = ctf_list_next (dmd))
1686 {
1687 if (strcmp (dmd->dmd_name, name) == 0)
1688 {
1689 if (valp != NULL)
1690 *valp = dmd->dmd_value;
1691 return 0;
1692 }
1693 }
1694 }
1695
1696 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1697 return -1;
1698 }
1699
1700 /* Given a type ID relating to a function type, return info on return types and
1701 arg counts for that function. */
1702
1703 int
1704 ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1705 {
1706 const ctf_type_t *tp;
1707 uint32_t kind;
1708 const uint32_t *args;
1709 const ctf_dtdef_t *dtd;
1710 ssize_t size, increment;
1711
1712 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1713 return -1; /* errno is set for us. */
1714
1715 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1716 return -1; /* errno is set for us. */
1717
1718 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1719 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1720
1721 if (kind != CTF_K_FUNCTION)
1722 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1723
1724 fip->ctc_return = tp->ctt_type;
1725 fip->ctc_flags = 0;
1726 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1727
1728 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1729 args = (uint32_t *) ((uintptr_t) tp + increment);
1730 else
1731 args = dtd->dtd_u.dtu_argv;
1732
1733 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1734 {
1735 fip->ctc_flags |= CTF_FUNC_VARARG;
1736 fip->ctc_argc--;
1737 }
1738
1739 return 0;
1740 }
1741
1742 /* Given a type ID relating to a function type, return the arguments for the
1743 function. */
1744
1745 int
1746 ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1747 {
1748 const ctf_type_t *tp;
1749 const uint32_t *args;
1750 const ctf_dtdef_t *dtd;
1751 ssize_t size, increment;
1752 ctf_funcinfo_t f;
1753
1754 if (ctf_func_type_info (fp, type, &f) < 0)
1755 return -1; /* errno is set for us. */
1756
1757 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1758 return -1; /* errno is set for us. */
1759
1760 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1761 return -1; /* errno is set for us. */
1762
1763 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1764
1765 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1766 args = (uint32_t *) ((uintptr_t) tp + increment);
1767 else
1768 args = dtd->dtd_u.dtu_argv;
1769
1770 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1771 *argv++ = *args++;
1772
1773 return 0;
1774 }
1775
1776 /* Recursively visit the members of any type. This function is used as the
1777 engine for ctf_type_visit, below. We resolve the input type, recursively
1778 invoke ourself for each type member if the type is a struct or union, and
1779 then invoke the callback function on the current type. If any callback
1780 returns non-zero, we abort and percolate the error code back up to the top. */
1781
1782 static int
1783 ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
1784 void *arg, const char *name, unsigned long offset, int depth)
1785 {
1786 ctf_id_t otype = type;
1787 const ctf_type_t *tp;
1788 const ctf_dtdef_t *dtd;
1789 ssize_t size, increment;
1790 uint32_t kind, n;
1791 int rc;
1792
1793 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1794 return -1; /* errno is set for us. */
1795
1796 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1797 return -1; /* errno is set for us. */
1798
1799 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1800 return rc;
1801
1802 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1803
1804 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1805 return 0;
1806
1807 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1808
1809 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1810 {
1811 if (size < CTF_LSTRUCT_THRESH)
1812 {
1813 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1814 increment);
1815
1816 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1817 {
1818 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1819 func, arg, ctf_strptr (fp,
1820 mp->ctm_name),
1821 offset + mp->ctm_offset,
1822 depth + 1)) != 0)
1823 return rc;
1824 }
1825 }
1826 else
1827 {
1828 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1829 increment);
1830
1831 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1832 {
1833 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1834 func, arg, ctf_strptr (fp,
1835 lmp->ctlm_name),
1836 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1837 depth + 1)) != 0)
1838 return rc;
1839 }
1840 }
1841 }
1842 else
1843 {
1844 ctf_dmdef_t *dmd;
1845
1846 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1847 dmd != NULL; dmd = ctf_list_next (dmd))
1848 {
1849 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1850 dmd->dmd_name, dmd->dmd_offset,
1851 depth + 1)) != 0)
1852 return rc;
1853 }
1854 }
1855
1856 return 0;
1857 }
1858
1859 /* Recursively visit the members of any type. We pass the name, member
1860 type, and offset of each member to the specified callback function. */
1861 int
1862 ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1863 {
1864 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1865 }