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