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