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