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