libctf, binutils, include, ld: gettextize and improve error handling
[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_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
610 otype);
611 return (ctf_set_errno (ofp, ECTF_CORRUPT));
612 }
613 prev = type;
614 type = tp->ctt_type;
615 break;
616 default:
617 return type;
618 }
619 if (type == 0)
620 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
621 }
622
623 return CTF_ERR; /* errno is set for us. */
624 }
625
626 /* Like ctf_type_resolve(), but traverse down through slices to their contained
627 type. */
628
629 ctf_id_t
630 ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
631 {
632 const ctf_type_t *tp;
633
634 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
635 return -1;
636
637 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
638 return CTF_ERR; /* errno is set for us. */
639
640 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
641 return ctf_type_reference (fp, type);
642 return type;
643 }
644
645 /* Look up a name in the given name table, in the appropriate hash given the
646 kind of the identifier. The name is a raw, undecorated identifier. */
647
648 ctf_id_t ctf_lookup_by_rawname (ctf_file_t *fp, int kind, const char *name)
649 {
650 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
651 }
652
653 /* Look up a name in the given name table, in the appropriate hash given the
654 readability state of the dictionary. The name is a raw, undecorated
655 identifier. */
656
657 ctf_id_t ctf_lookup_by_rawhash (ctf_file_t *fp, ctf_names_t *np, const char *name)
658 {
659 ctf_id_t id;
660
661 if (fp->ctf_flags & LCTF_RDWR)
662 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
663 else
664 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
665 return id;
666 }
667
668 /* Lookup the given type ID and return its name as a new dynamically-allocated
669 string. */
670
671 char *
672 ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
673 {
674 ctf_decl_t cd;
675 ctf_decl_node_t *cdp;
676 ctf_decl_prec_t prec, lp, rp;
677 int ptr, arr;
678 uint32_t k;
679 char *buf;
680
681 if (fp == NULL && type == CTF_ERR)
682 return NULL; /* Simplify caller code by permitting CTF_ERR. */
683
684 ctf_decl_init (&cd);
685 ctf_decl_push (&cd, fp, type);
686
687 if (cd.cd_err != 0)
688 {
689 ctf_decl_fini (&cd);
690 ctf_set_errno (fp, cd.cd_err);
691 return NULL;
692 }
693
694 /* If the type graph's order conflicts with lexical precedence order
695 for pointers or arrays, then we need to surround the declarations at
696 the corresponding lexical precedence with parentheses. This can
697 result in either a parenthesized pointer (*) as in int (*)() or
698 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
699
700 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
701 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
702
703 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
704 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
705
706 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
707
708 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
709 {
710 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
711 cdp != NULL; cdp = ctf_list_next (cdp))
712 {
713 ctf_file_t *rfp = fp;
714 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
715 const char *name = ctf_strptr (rfp, tp->ctt_name);
716
717 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
718 ctf_decl_sprintf (&cd, " ");
719
720 if (lp == prec)
721 {
722 ctf_decl_sprintf (&cd, "(");
723 lp = -1;
724 }
725
726 switch (cdp->cd_kind)
727 {
728 case CTF_K_INTEGER:
729 case CTF_K_FLOAT:
730 case CTF_K_TYPEDEF:
731 /* Integers, floats, and typedefs must always be named types. */
732
733 if (name[0] == '\0')
734 {
735 ctf_set_errno (fp, ECTF_CORRUPT);
736 ctf_decl_fini (&cd);
737 return NULL;
738 }
739
740 ctf_decl_sprintf (&cd, "%s", name);
741 break;
742 case CTF_K_POINTER:
743 ctf_decl_sprintf (&cd, "*");
744 break;
745 case CTF_K_ARRAY:
746 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
747 break;
748 case CTF_K_FUNCTION:
749 {
750 size_t i;
751 ctf_funcinfo_t fi;
752 ctf_id_t *argv = NULL;
753
754 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
755 goto err; /* errno is set for us. */
756
757 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
758 {
759 ctf_set_errno (rfp, errno);
760 goto err;
761 }
762
763 if (ctf_func_type_args (rfp, cdp->cd_type,
764 fi.ctc_argc, argv) < 0)
765 goto err; /* errno is set for us. */
766
767 ctf_decl_sprintf (&cd, "(*) (");
768 for (i = 0; i < fi.ctc_argc; i++)
769 {
770 char *arg = ctf_type_aname (rfp, argv[i]);
771
772 if (arg == NULL)
773 goto err; /* errno is set for us. */
774 ctf_decl_sprintf (&cd, "%s", arg);
775 free (arg);
776
777 if ((i < fi.ctc_argc - 1)
778 || (fi.ctc_flags & CTF_FUNC_VARARG))
779 ctf_decl_sprintf (&cd, ", ");
780 }
781
782 if (fi.ctc_flags & CTF_FUNC_VARARG)
783 ctf_decl_sprintf (&cd, "...");
784 ctf_decl_sprintf (&cd, ")");
785
786 free (argv);
787 break;
788
789 err:
790 free (argv);
791 ctf_decl_fini (&cd);
792 return NULL;
793 }
794 break;
795 case CTF_K_STRUCT:
796 case CTF_K_FORWARD:
797 ctf_decl_sprintf (&cd, "struct %s", name);
798 break;
799 case CTF_K_UNION:
800 ctf_decl_sprintf (&cd, "union %s", name);
801 break;
802 case CTF_K_ENUM:
803 ctf_decl_sprintf (&cd, "enum %s", name);
804 break;
805 case CTF_K_VOLATILE:
806 ctf_decl_sprintf (&cd, "volatile");
807 break;
808 case CTF_K_CONST:
809 ctf_decl_sprintf (&cd, "const");
810 break;
811 case CTF_K_RESTRICT:
812 ctf_decl_sprintf (&cd, "restrict");
813 break;
814 case CTF_K_SLICE:
815 /* No representation: just changes encoding of contained type,
816 which is not in any case printed. Skip it. */
817 break;
818 }
819
820 k = cdp->cd_kind;
821 }
822
823 if (rp == prec)
824 ctf_decl_sprintf (&cd, ")");
825 }
826
827 if (cd.cd_enomem)
828 (void) ctf_set_errno (fp, ENOMEM);
829
830 buf = ctf_decl_buf (&cd);
831
832 ctf_decl_fini (&cd);
833 return buf;
834 }
835
836 /* Lookup the given type ID and print a string name for it into buf. Return
837 the actual number of bytes (not including \0) needed to format the name. */
838
839 ssize_t
840 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
841 {
842 char *str = ctf_type_aname (fp, type);
843 size_t slen;
844
845 if (str == NULL)
846 return CTF_ERR; /* errno is set for us. */
847
848 slen = strlen (str);
849 snprintf (buf, len, "%s", str);
850 free (str);
851
852 if (slen >= len)
853 (void) ctf_set_errno (fp, ECTF_NAMELEN);
854
855 return slen;
856 }
857
858 /* Lookup the given type ID and print a string name for it into buf. If buf
859 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
860
861 char *
862 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
863 {
864 ssize_t rv = ctf_type_lname (fp, type, buf, len);
865 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
866 }
867
868 /* Lookup the given type ID and return its raw, unadorned, undecorated name.
869 The name will live as long as its ctf_file_t does. */
870
871 const char *
872 ctf_type_name_raw (ctf_file_t *fp, ctf_id_t type)
873 {
874 const ctf_type_t *tp;
875
876 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
877 return NULL; /* errno is set for us. */
878
879 return ctf_strraw (fp, tp->ctt_name);
880 }
881
882 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
883 new dynamically-allocated string. */
884
885 char *
886 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
887 {
888 const char *name = ctf_type_name_raw (fp, type);
889
890 if (name != NULL)
891 return strdup (name);
892
893 return NULL;
894 }
895
896 /* Resolve the type down to a base type node, and then return the size
897 of the type storage in bytes. */
898
899 ssize_t
900 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
901 {
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 (fp, type, &ar) < 0
934 || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
935 return -1; /* errno is set for us. */
936
937 return size * ar.ctr_nelems;
938
939 default: /* including slices of enums, etc */
940 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
941 }
942 }
943
944 /* Resolve the type down to a base type node, and then return the alignment
945 needed for the type storage in bytes.
946
947 XXX may need arch-dependent attention. */
948
949 ssize_t
950 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
951 {
952 const ctf_type_t *tp;
953 ctf_file_t *ofp = fp;
954 int kind;
955
956 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
957 return -1; /* errno is set for us. */
958
959 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
960 return -1; /* errno is set for us. */
961
962 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
963 switch (kind)
964 {
965 case CTF_K_POINTER:
966 case CTF_K_FUNCTION:
967 return fp->ctf_dmodel->ctd_pointer;
968
969 case CTF_K_ARRAY:
970 {
971 ctf_arinfo_t r;
972 if (ctf_array_info (fp, type, &r) < 0)
973 return -1; /* errno is set for us. */
974 return (ctf_type_align (fp, r.ctr_contents));
975 }
976
977 case CTF_K_STRUCT:
978 case CTF_K_UNION:
979 {
980 size_t align = 0;
981 ctf_dtdef_t *dtd;
982
983 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
984 {
985 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
986 ssize_t size, increment;
987 const void *vmp;
988
989 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
990 vmp = (unsigned char *) tp + increment;
991
992 if (kind == CTF_K_STRUCT)
993 n = MIN (n, 1); /* Only use first member for structs. */
994
995 if (size < CTF_LSTRUCT_THRESH)
996 {
997 const ctf_member_t *mp = vmp;
998 for (; n != 0; n--, mp++)
999 {
1000 ssize_t am = ctf_type_align (fp, mp->ctm_type);
1001 align = MAX (align, (size_t) am);
1002 }
1003 }
1004 else
1005 {
1006 const ctf_lmember_t *lmp = vmp;
1007 for (; n != 0; n--, lmp++)
1008 {
1009 ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
1010 align = MAX (align, (size_t) am);
1011 }
1012 }
1013 }
1014 else
1015 {
1016 ctf_dmdef_t *dmd;
1017
1018 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1019 dmd != NULL; dmd = ctf_list_next (dmd))
1020 {
1021 ssize_t am = ctf_type_align (fp, dmd->dmd_type);
1022 align = MAX (align, (size_t) am);
1023 if (kind == CTF_K_STRUCT)
1024 break;
1025 }
1026 }
1027
1028 return align;
1029 }
1030
1031 case CTF_K_ENUM:
1032 return fp->ctf_dmodel->ctd_int;
1033
1034 default: /* including slices of enums, etc */
1035 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1036 }
1037 }
1038
1039 /* Return the kind (CTF_K_* constant) for the specified type ID. */
1040
1041 int
1042 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
1043 {
1044 const ctf_type_t *tp;
1045
1046 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1047 return -1; /* errno is set for us. */
1048
1049 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1050 }
1051
1052 /* Return the kind (CTF_K_* constant) for the specified type ID.
1053 Slices are considered to be of the same kind as the type sliced. */
1054
1055 int
1056 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
1057 {
1058 int kind;
1059
1060 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1061 return -1;
1062
1063 if (kind == CTF_K_SLICE)
1064 {
1065 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
1066 return -1;
1067 kind = ctf_type_kind_unsliced (fp, type);
1068 }
1069
1070 return kind;
1071 }
1072
1073 /* Return the kind of this type, except, for forwards, return the kind of thing
1074 this is a forward to. */
1075 int
1076 ctf_type_kind_forwarded (ctf_file_t *fp, ctf_id_t type)
1077 {
1078 int kind;
1079 const ctf_type_t *tp;
1080
1081 if ((kind = ctf_type_kind (fp, type)) < 0)
1082 return -1; /* errno is set for us. */
1083
1084 if (kind != CTF_K_FORWARD)
1085 return kind;
1086
1087 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1088 return -1; /* errno is set for us. */
1089
1090 return tp->ctt_type;
1091 }
1092
1093 /* If the type is one that directly references another type (such as POINTER),
1094 then return the ID of the type to which it refers. */
1095
1096 ctf_id_t
1097 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
1098 {
1099 ctf_file_t *ofp = fp;
1100 const ctf_type_t *tp;
1101
1102 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1103 return CTF_ERR; /* errno is set for us. */
1104
1105 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1106 {
1107 case CTF_K_POINTER:
1108 case CTF_K_TYPEDEF:
1109 case CTF_K_VOLATILE:
1110 case CTF_K_CONST:
1111 case CTF_K_RESTRICT:
1112 return tp->ctt_type;
1113 /* Slices store their type in an unusual place. */
1114 case CTF_K_SLICE:
1115 {
1116 ctf_dtdef_t *dtd;
1117 const ctf_slice_t *sp;
1118
1119 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1120 {
1121 ssize_t increment;
1122
1123 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1124 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1125 }
1126 else
1127 sp = &dtd->dtd_u.dtu_slice;
1128
1129 return sp->cts_type;
1130 }
1131 default:
1132 return (ctf_set_errno (ofp, ECTF_NOTREF));
1133 }
1134 }
1135
1136 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1137 pointer to the given type, see if we can compute a pointer to the type
1138 resulting from resolving the type down to its base type and use that
1139 instead. This helps with cases where the CTF data includes "struct foo *"
1140 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1141
1142 XXX what about parent containers? */
1143
1144 ctf_id_t
1145 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
1146 {
1147 ctf_file_t *ofp = fp;
1148 ctf_id_t ntype;
1149
1150 if (ctf_lookup_by_id (&fp, type) == NULL)
1151 return CTF_ERR; /* errno is set for us. */
1152
1153 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1154 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1155
1156 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1157 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1158
1159 if (ctf_lookup_by_id (&fp, type) == NULL)
1160 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1161
1162 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1163 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1164
1165 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1166 }
1167
1168 /* Return the encoding for the specified INTEGER or FLOAT. */
1169
1170 int
1171 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
1172 {
1173 ctf_file_t *ofp = fp;
1174 ctf_dtdef_t *dtd;
1175 const ctf_type_t *tp;
1176 ssize_t increment;
1177 uint32_t data;
1178
1179 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1180 return -1; /* errno is set for us. */
1181
1182 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1183 {
1184 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1185 {
1186 case CTF_K_INTEGER:
1187 case CTF_K_FLOAT:
1188 *ep = dtd->dtd_u.dtu_enc;
1189 break;
1190 case CTF_K_SLICE:
1191 {
1192 const ctf_slice_t *slice;
1193 ctf_encoding_t underlying_en;
1194 ctf_id_t underlying;
1195
1196 slice = &dtd->dtd_u.dtu_slice;
1197 underlying = ctf_type_resolve (fp, slice->cts_type);
1198 data = ctf_type_encoding (fp, underlying, &underlying_en);
1199
1200 ep->cte_format = underlying_en.cte_format;
1201 ep->cte_offset = slice->cts_offset;
1202 ep->cte_bits = slice->cts_bits;
1203 break;
1204 }
1205 default:
1206 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1207 }
1208 return 0;
1209 }
1210
1211 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1212
1213 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1214 {
1215 case CTF_K_INTEGER:
1216 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1217 ep->cte_format = CTF_INT_ENCODING (data);
1218 ep->cte_offset = CTF_INT_OFFSET (data);
1219 ep->cte_bits = CTF_INT_BITS (data);
1220 break;
1221 case CTF_K_FLOAT:
1222 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1223 ep->cte_format = CTF_FP_ENCODING (data);
1224 ep->cte_offset = CTF_FP_OFFSET (data);
1225 ep->cte_bits = CTF_FP_BITS (data);
1226 break;
1227 case CTF_K_SLICE:
1228 {
1229 const ctf_slice_t *slice;
1230 ctf_encoding_t underlying_en;
1231 ctf_id_t underlying;
1232
1233 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
1234 underlying = ctf_type_resolve (fp, slice->cts_type);
1235 data = ctf_type_encoding (fp, underlying, &underlying_en);
1236
1237 ep->cte_format = underlying_en.cte_format;
1238 ep->cte_offset = slice->cts_offset;
1239 ep->cte_bits = slice->cts_bits;
1240 break;
1241 }
1242 default:
1243 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1244 }
1245
1246 return 0;
1247 }
1248
1249 int
1250 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
1251 ctf_id_t rtype)
1252 {
1253 int rval;
1254
1255 if (ltype < rtype)
1256 rval = -1;
1257 else if (ltype > rtype)
1258 rval = 1;
1259 else
1260 rval = 0;
1261
1262 if (lfp == rfp)
1263 return rval;
1264
1265 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1266 lfp = lfp->ctf_parent;
1267
1268 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1269 rfp = rfp->ctf_parent;
1270
1271 if (lfp < rfp)
1272 return -1;
1273
1274 if (lfp > rfp)
1275 return 1;
1276
1277 return rval;
1278 }
1279
1280 /* Return a boolean value indicating if two types are compatible. This function
1281 returns true if the two types are the same, or if they (or their ultimate
1282 base type) have the same encoding properties, or (for structs / unions /
1283 enums / forward declarations) if they have the same name and (for structs /
1284 unions) member count. */
1285
1286 int
1287 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
1288 ctf_file_t *rfp, ctf_id_t rtype)
1289 {
1290 const ctf_type_t *ltp, *rtp;
1291 ctf_encoding_t le, re;
1292 ctf_arinfo_t la, ra;
1293 uint32_t lkind, rkind;
1294 int same_names = 0;
1295
1296 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1297 return 1;
1298
1299 ltype = ctf_type_resolve (lfp, ltype);
1300 lkind = ctf_type_kind (lfp, ltype);
1301
1302 rtype = ctf_type_resolve (rfp, rtype);
1303 rkind = ctf_type_kind (rfp, rtype);
1304
1305 ltp = ctf_lookup_by_id (&lfp, ltype);
1306 rtp = ctf_lookup_by_id (&rfp, rtype);
1307
1308 if (ltp != NULL && rtp != NULL)
1309 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1310 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1311
1312 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1313 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1314 return 1;
1315
1316 if (lkind != rkind)
1317 return 0;
1318
1319 switch (lkind)
1320 {
1321 case CTF_K_INTEGER:
1322 case CTF_K_FLOAT:
1323 memset (&le, 0, sizeof (le));
1324 memset (&re, 0, sizeof (re));
1325 return (ctf_type_encoding (lfp, ltype, &le) == 0
1326 && ctf_type_encoding (rfp, rtype, &re) == 0
1327 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1328 case CTF_K_POINTER:
1329 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1330 rfp, ctf_type_reference (rfp, rtype)));
1331 case CTF_K_ARRAY:
1332 return (ctf_array_info (lfp, ltype, &la) == 0
1333 && ctf_array_info (rfp, rtype, &ra) == 0
1334 && la.ctr_nelems == ra.ctr_nelems
1335 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1336 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1337 case CTF_K_STRUCT:
1338 case CTF_K_UNION:
1339 return (same_names && (ctf_type_size (lfp, ltype)
1340 == ctf_type_size (rfp, rtype)));
1341 case CTF_K_ENUM:
1342 {
1343 int lencoded, rencoded;
1344 lencoded = ctf_type_encoding (lfp, ltype, &le);
1345 rencoded = ctf_type_encoding (rfp, rtype, &re);
1346
1347 if ((lencoded != rencoded) ||
1348 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1349 return 0;
1350 }
1351 /* FALLTHRU */
1352 case CTF_K_FORWARD:
1353 return same_names; /* No other checks required for these type kinds. */
1354 default:
1355 return 0; /* Should not get here since we did a resolve. */
1356 }
1357 }
1358
1359 /* Return the number of members in a STRUCT or UNION, or the number of
1360 enumerators in an ENUM. */
1361
1362 int
1363 ctf_member_count (ctf_file_t *fp, ctf_id_t type)
1364 {
1365 ctf_file_t *ofp = fp;
1366 const ctf_type_t *tp;
1367 uint32_t kind;
1368
1369 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1370 return -1; /* errno is set for us. */
1371
1372 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1373 return -1; /* errno is set for us. */
1374
1375 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1376
1377 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1378 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1379
1380 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1381 }
1382
1383 /* Return the type and offset for a given member of a STRUCT or UNION. */
1384
1385 int
1386 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
1387 ctf_membinfo_t *mip)
1388 {
1389 ctf_file_t *ofp = fp;
1390 const ctf_type_t *tp;
1391 ctf_dtdef_t *dtd;
1392 ssize_t size, increment;
1393 uint32_t kind, n;
1394
1395 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1396 return -1; /* errno is set for us. */
1397
1398 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1399 return -1; /* errno is set for us. */
1400
1401 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1402 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1403
1404 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1405 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1406
1407 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1408 {
1409 if (size < CTF_LSTRUCT_THRESH)
1410 {
1411 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1412 increment);
1413
1414 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1415 {
1416 if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
1417 {
1418 mip->ctm_type = mp->ctm_type;
1419 mip->ctm_offset = mp->ctm_offset;
1420 return 0;
1421 }
1422 }
1423 }
1424 else
1425 {
1426 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1427 increment);
1428
1429 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1430 {
1431 if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
1432 {
1433 mip->ctm_type = lmp->ctlm_type;
1434 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1435 return 0;
1436 }
1437 }
1438 }
1439 }
1440 else
1441 {
1442 ctf_dmdef_t *dmd;
1443
1444 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1445 dmd != NULL; dmd = ctf_list_next (dmd))
1446 {
1447 if (strcmp (dmd->dmd_name, name) == 0)
1448 {
1449 mip->ctm_type = dmd->dmd_type;
1450 mip->ctm_offset = dmd->dmd_offset;
1451 return 0;
1452 }
1453 }
1454 }
1455
1456 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1457 }
1458
1459 /* Return the array type, index, and size information for the specified ARRAY. */
1460
1461 int
1462 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
1463 {
1464 ctf_file_t *ofp = fp;
1465 const ctf_type_t *tp;
1466 const ctf_array_t *ap;
1467 const ctf_dtdef_t *dtd;
1468 ssize_t increment;
1469
1470 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1471 return -1; /* errno is set for us. */
1472
1473 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1474 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1475
1476 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1477 {
1478 *arp = dtd->dtd_u.dtu_arr;
1479 return 0;
1480 }
1481
1482 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1483
1484 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1485 arp->ctr_contents = ap->cta_contents;
1486 arp->ctr_index = ap->cta_index;
1487 arp->ctr_nelems = ap->cta_nelems;
1488
1489 return 0;
1490 }
1491
1492 /* Convert the specified value to the corresponding enum tag name, if a
1493 matching name can be found. Otherwise NULL is returned. */
1494
1495 const char *
1496 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1497 {
1498 ctf_file_t *ofp = fp;
1499 const ctf_type_t *tp;
1500 const ctf_enum_t *ep;
1501 const ctf_dtdef_t *dtd;
1502 ssize_t increment;
1503 uint32_t n;
1504
1505 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1506 return NULL; /* errno is set for us. */
1507
1508 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1509 return NULL; /* errno is set for us. */
1510
1511 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1512 {
1513 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1514 return NULL;
1515 }
1516
1517 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1518
1519 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1520 {
1521 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1522
1523 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1524 {
1525 if (ep->cte_value == value)
1526 return (ctf_strptr (fp, ep->cte_name));
1527 }
1528 }
1529 else
1530 {
1531 ctf_dmdef_t *dmd;
1532
1533 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1534 dmd != NULL; dmd = ctf_list_next (dmd))
1535 {
1536 if (dmd->dmd_value == value)
1537 return dmd->dmd_name;
1538 }
1539 }
1540
1541 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1542 return NULL;
1543 }
1544
1545 /* Convert the specified enum tag name to the corresponding value, if a
1546 matching name can be found. Otherwise CTF_ERR is returned. */
1547
1548 int
1549 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1550 {
1551 ctf_file_t *ofp = fp;
1552 const ctf_type_t *tp;
1553 const ctf_enum_t *ep;
1554 const ctf_dtdef_t *dtd;
1555 ssize_t increment;
1556 uint32_t n;
1557
1558 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1559 return -1; /* errno is set for us. */
1560
1561 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1562 return -1; /* errno is set for us. */
1563
1564 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1565 {
1566 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1567 return -1;
1568 }
1569
1570 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1571
1572 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1573
1574 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1575 {
1576 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1577 {
1578 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1579 {
1580 if (valp != NULL)
1581 *valp = ep->cte_value;
1582 return 0;
1583 }
1584 }
1585 }
1586 else
1587 {
1588 ctf_dmdef_t *dmd;
1589
1590 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1591 dmd != NULL; dmd = ctf_list_next (dmd))
1592 {
1593 if (strcmp (dmd->dmd_name, name) == 0)
1594 {
1595 if (valp != NULL)
1596 *valp = dmd->dmd_value;
1597 return 0;
1598 }
1599 }
1600 }
1601
1602 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1603 return -1;
1604 }
1605
1606 /* Given a type ID relating to a function type, return info on return types and
1607 arg counts for that function. */
1608
1609 int
1610 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1611 {
1612 const ctf_type_t *tp;
1613 uint32_t kind;
1614 const uint32_t *args;
1615 const ctf_dtdef_t *dtd;
1616 ssize_t size, increment;
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 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1626
1627 if (kind != CTF_K_FUNCTION)
1628 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1629
1630 fip->ctc_return = tp->ctt_type;
1631 fip->ctc_flags = 0;
1632 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1633
1634 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1635 args = (uint32_t *) ((uintptr_t) tp + increment);
1636 else
1637 args = dtd->dtd_u.dtu_argv;
1638
1639 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1640 {
1641 fip->ctc_flags |= CTF_FUNC_VARARG;
1642 fip->ctc_argc--;
1643 }
1644
1645 return 0;
1646 }
1647
1648 /* Given a type ID relating to a function type, return the arguments for the
1649 function. */
1650
1651 int
1652 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1653 {
1654 const ctf_type_t *tp;
1655 const uint32_t *args;
1656 const ctf_dtdef_t *dtd;
1657 ssize_t size, increment;
1658 ctf_funcinfo_t f;
1659
1660 if (ctf_func_type_info (fp, type, &f) < 0)
1661 return -1; /* errno is set for us. */
1662
1663 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1664 return -1; /* errno is set for us. */
1665
1666 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1667 return -1; /* errno is set for us. */
1668
1669 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1670
1671 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1672 args = (uint32_t *) ((uintptr_t) tp + increment);
1673 else
1674 args = dtd->dtd_u.dtu_argv;
1675
1676 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1677 *argv++ = *args++;
1678
1679 return 0;
1680 }
1681
1682 /* Recursively visit the members of any type. This function is used as the
1683 engine for ctf_type_visit, below. We resolve the input type, recursively
1684 invoke ourself for each type member if the type is a struct or union, and
1685 then invoke the callback function on the current type. If any callback
1686 returns non-zero, we abort and percolate the error code back up to the top. */
1687
1688 static int
1689 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1690 void *arg, const char *name, unsigned long offset, int depth)
1691 {
1692 ctf_id_t otype = type;
1693 const ctf_type_t *tp;
1694 const ctf_dtdef_t *dtd;
1695 ssize_t size, increment;
1696 uint32_t kind, n;
1697 int rc;
1698
1699 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1700 return -1; /* errno is set for us. */
1701
1702 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1703 return -1; /* errno is set for us. */
1704
1705 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1706 return rc;
1707
1708 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1709
1710 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1711 return 0;
1712
1713 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1714
1715 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1716 {
1717 if (size < CTF_LSTRUCT_THRESH)
1718 {
1719 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1720 increment);
1721
1722 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1723 {
1724 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1725 func, arg, ctf_strptr (fp,
1726 mp->ctm_name),
1727 offset + mp->ctm_offset,
1728 depth + 1)) != 0)
1729 return rc;
1730 }
1731 }
1732 else
1733 {
1734 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1735 increment);
1736
1737 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1738 {
1739 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1740 func, arg, ctf_strptr (fp,
1741 lmp->ctlm_name),
1742 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1743 depth + 1)) != 0)
1744 return rc;
1745 }
1746 }
1747 }
1748 else
1749 {
1750 ctf_dmdef_t *dmd;
1751
1752 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1753 dmd != NULL; dmd = ctf_list_next (dmd))
1754 {
1755 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1756 dmd->dmd_name, dmd->dmd_offset,
1757 depth + 1)) != 0)
1758 return rc;
1759 }
1760 }
1761
1762 return 0;
1763 }
1764
1765 /* Recursively visit the members of any type. We pass the name, member
1766 type, and offset of each member to the specified callback function. */
1767 int
1768 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1769 {
1770 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1771 }