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