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