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