libctf: add the ctf_link machinery
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
1 /* Type handling functions.
2 Copyright (C) 2019 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <ctf-impl.h>
21 #include <string.h>
22
23 /* Determine whether a type is a parent or a child. */
24
25 int
26 ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27 {
28 return (LCTF_TYPE_ISPARENT (fp, id));
29 }
30
31 int
32 ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33 {
34 return (LCTF_TYPE_ISCHILD (fp, id));
35 }
36
37 /* Iterate over the members of a STRUCT or UNION. We pass the name, member
38 type, and offset of each member to the specified callback function. */
39
40 int
41 ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42 {
43 ctf_file_t *ofp = fp;
44 const ctf_type_t *tp;
45 ssize_t size, increment;
46 uint32_t kind, n;
47 int rc;
48
49 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
50 return -1; /* errno is set for us. */
51
52 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
53 return -1; /* errno is set for us. */
54
55 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
56 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
57
58 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
59 return (ctf_set_errno (ofp, ECTF_NOTSOU));
60
61 if (size < CTF_LSTRUCT_THRESH)
62 {
63 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
64 increment);
65
66 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
67 {
68 const char *name = ctf_strptr (fp, mp->ctm_name);
69 if ((rc = func (name, mp->ctm_type, mp->ctm_offset, arg)) != 0)
70 return rc;
71 }
72
73 }
74 else
75 {
76 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
77 increment);
78
79 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
80 {
81 const char *name = ctf_strptr (fp, lmp->ctlm_name);
82 if ((rc = func (name, lmp->ctlm_type,
83 (unsigned long) CTF_LMEM_OFFSET (lmp), arg)) != 0)
84 return rc;
85 }
86 }
87
88 return 0;
89 }
90
91 /* Iterate over the members of an ENUM. We pass the string name and associated
92 integer value of each enum element to the specified callback function. */
93
94 int
95 ctf_enum_iter (ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
96 {
97 ctf_file_t *ofp = fp;
98 const ctf_type_t *tp;
99 const ctf_enum_t *ep;
100 ssize_t increment;
101 uint32_t n;
102 int rc;
103
104 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
105 return -1; /* errno is set for us. */
106
107 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
108 return -1; /* errno is set for us. */
109
110 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
111 return (ctf_set_errno (ofp, ECTF_NOTENUM));
112
113 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
114
115 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
116
117 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
118 {
119 const char *name = ctf_strptr (fp, ep->cte_name);
120 if ((rc = func (name, ep->cte_value, arg)) != 0)
121 return rc;
122 }
123
124 return 0;
125 }
126
127 /* Iterate over every root (user-visible) type in the given CTF container.
128 We pass the type ID of each type to the specified callback function. */
129
130 int
131 ctf_type_iter (ctf_file_t *fp, ctf_type_f *func, void *arg)
132 {
133 ctf_id_t id, max = fp->ctf_typemax;
134 int rc, child = (fp->ctf_flags & LCTF_CHILD);
135
136 for (id = 1; id <= max; id++)
137 {
138 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
139 if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
140 && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
141 return rc;
142 }
143
144 return 0;
145 }
146
147 /* Iterate over every type in the given CTF container, user-visible or not.
148 We pass the type ID of each type to the specified callback function. */
149
150 int
151 ctf_type_iter_all (ctf_file_t *fp, ctf_type_all_f *func, void *arg)
152 {
153 ctf_id_t id, max = fp->ctf_typemax;
154 int rc, child = (fp->ctf_flags & LCTF_CHILD);
155
156 for (id = 1; id <= max; id++)
157 {
158 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
159 if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
160 LCTF_INFO_ISROOT(fp, tp->ctt_info)
161 ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
162 return rc;
163 }
164
165 return 0;
166 }
167
168 /* Iterate over every variable in the given CTF container, in arbitrary order.
169 We pass the name of each variable to the specified callback function. */
170
171 int
172 ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
173 {
174 unsigned long i;
175 int rc;
176
177 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
178 return ECTF_NOPARENT;
179
180 for (i = 0; i < fp->ctf_nvars; i++)
181 if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
182 fp->ctf_vars[i].ctv_type, arg)) != 0)
183 return rc;
184
185 return 0;
186 }
187
188 /* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
189 RESTRICT nodes until we reach a "base" type node. This is useful when
190 we want to follow a type ID to a node that has members or a size. To guard
191 against infinite loops, we implement simplified cycle detection and check
192 each link against itself, the previous node, and the topmost node.
193
194 Does not drill down through slices to their contained type. */
195
196 ctf_id_t
197 ctf_type_resolve (ctf_file_t *fp, ctf_id_t type)
198 {
199 ctf_id_t prev = type, otype = type;
200 ctf_file_t *ofp = fp;
201 const ctf_type_t *tp;
202
203 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
204 {
205 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
206 {
207 case CTF_K_TYPEDEF:
208 case CTF_K_VOLATILE:
209 case CTF_K_CONST:
210 case CTF_K_RESTRICT:
211 if (tp->ctt_type == type || tp->ctt_type == otype
212 || tp->ctt_type == prev)
213 {
214 ctf_dprintf ("type %ld cycle detected\n", otype);
215 return (ctf_set_errno (ofp, ECTF_CORRUPT));
216 }
217 prev = type;
218 type = tp->ctt_type;
219 break;
220 default:
221 return type;
222 }
223 }
224
225 return CTF_ERR; /* errno is set for us. */
226 }
227
228 /* Like ctf_type_resolve(), but traverse down through slices to their contained
229 type. */
230
231 ctf_id_t
232 ctf_type_resolve_unsliced (ctf_file_t *fp, ctf_id_t type)
233 {
234 const ctf_type_t *tp;
235
236 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
237 return -1;
238
239 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
240 return CTF_ERR; /* errno is set for us. */
241
242 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
243 return ctf_type_reference (fp, type);
244 return type;
245 }
246
247 /* Lookup the given type ID and return its name as a new dynamcally-allocated
248 string. */
249
250 char *
251 ctf_type_aname (ctf_file_t *fp, ctf_id_t type)
252 {
253 ctf_decl_t cd;
254 ctf_decl_node_t *cdp;
255 ctf_decl_prec_t prec, lp, rp;
256 int ptr, arr;
257 uint32_t k;
258 char *buf;
259
260 if (fp == NULL && type == CTF_ERR)
261 return NULL; /* Simplify caller code by permitting CTF_ERR. */
262
263 ctf_decl_init (&cd);
264 ctf_decl_push (&cd, fp, type);
265
266 if (cd.cd_err != 0)
267 {
268 ctf_decl_fini (&cd);
269 ctf_set_errno (fp, cd.cd_err);
270 return NULL;
271 }
272
273 /* If the type graph's order conflicts with lexical precedence order
274 for pointers or arrays, then we need to surround the declarations at
275 the corresponding lexical precedence with parentheses. This can
276 result in either a parenthesized pointer (*) as in int (*)() or
277 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
278
279 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
280 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
281
282 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
283 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
284
285 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
286
287 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
288 {
289 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
290 cdp != NULL; cdp = ctf_list_next (cdp))
291 {
292 ctf_file_t *rfp = fp;
293 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
294 const char *name = ctf_strptr (rfp, tp->ctt_name);
295
296 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
297 ctf_decl_sprintf (&cd, " ");
298
299 if (lp == prec)
300 {
301 ctf_decl_sprintf (&cd, "(");
302 lp = -1;
303 }
304
305 switch (cdp->cd_kind)
306 {
307 case CTF_K_INTEGER:
308 case CTF_K_FLOAT:
309 case CTF_K_TYPEDEF:
310 ctf_decl_sprintf (&cd, "%s", name);
311 break;
312 case CTF_K_POINTER:
313 ctf_decl_sprintf (&cd, "*");
314 break;
315 case CTF_K_ARRAY:
316 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
317 break;
318 case CTF_K_FUNCTION:
319 ctf_decl_sprintf (&cd, "()");
320 break;
321 case CTF_K_STRUCT:
322 case CTF_K_FORWARD:
323 ctf_decl_sprintf (&cd, "struct %s", name);
324 break;
325 case CTF_K_UNION:
326 ctf_decl_sprintf (&cd, "union %s", name);
327 break;
328 case CTF_K_ENUM:
329 ctf_decl_sprintf (&cd, "enum %s", name);
330 break;
331 case CTF_K_VOLATILE:
332 ctf_decl_sprintf (&cd, "volatile");
333 break;
334 case CTF_K_CONST:
335 ctf_decl_sprintf (&cd, "const");
336 break;
337 case CTF_K_RESTRICT:
338 ctf_decl_sprintf (&cd, "restrict");
339 break;
340 case CTF_K_SLICE:
341 /* No representation: just changes encoding of contained type,
342 which is not in any case printed. Skip it. */
343 break;
344 }
345
346 k = cdp->cd_kind;
347 }
348
349 if (rp == prec)
350 ctf_decl_sprintf (&cd, ")");
351 }
352
353 if (cd.cd_enomem)
354 (void) ctf_set_errno (fp, ENOMEM);
355
356 buf = ctf_decl_buf (&cd);
357
358 ctf_decl_fini (&cd);
359 return buf;
360 }
361
362 /* Lookup the given type ID and print a string name for it into buf. Return
363 the actual number of bytes (not including \0) needed to format the name. */
364
365 ssize_t
366 ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
367 {
368 char *str = ctf_type_aname (fp, type);
369 size_t slen = strlen (str);
370
371 if (str == NULL)
372 return CTF_ERR; /* errno is set for us */
373
374 snprintf (buf, len, "%s", str);
375 free (str);
376
377 if (slen >= len)
378 (void) ctf_set_errno (fp, ECTF_NAMELEN);
379
380 return slen;
381 }
382
383 /* Lookup the given type ID and print a string name for it into buf. If buf
384 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
385
386 char *
387 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
388 {
389 ssize_t rv = ctf_type_lname (fp, type, buf, len);
390 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
391 }
392
393 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
394 new dynamcally-allocated string. */
395
396 char *
397 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
398 {
399 const ctf_type_t *tp;
400
401 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
402 return NULL; /* errno is set for us. */
403
404 if (ctf_strraw (fp, tp->ctt_name) != NULL)
405 return strdup (ctf_strraw (fp, tp->ctt_name));
406
407 return NULL;
408 }
409
410 /* Resolve the type down to a base type node, and then return the size
411 of the type storage in bytes. */
412
413 ssize_t
414 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
415 {
416 const ctf_type_t *tp;
417 ssize_t size;
418 ctf_arinfo_t ar;
419
420 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
421 return -1; /* errno is set for us. */
422
423 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
424 return -1; /* errno is set for us. */
425
426 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
427 {
428 case CTF_K_POINTER:
429 return fp->ctf_dmodel->ctd_pointer;
430
431 case CTF_K_FUNCTION:
432 return 0; /* Function size is only known by symtab. */
433
434 case CTF_K_ENUM:
435 return fp->ctf_dmodel->ctd_int;
436
437 case CTF_K_ARRAY:
438 /* ctf_add_array() does not directly encode the element size, but
439 requires the user to multiply to determine the element size.
440
441 If ctf_get_ctt_size() returns nonzero, then use the recorded
442 size instead. */
443
444 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
445 return size;
446
447 if (ctf_array_info (fp, type, &ar) < 0
448 || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
449 return -1; /* errno is set for us. */
450
451 return size * ar.ctr_nelems;
452
453 default: /* including slices of enums, etc */
454 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
455 }
456 }
457
458 /* Resolve the type down to a base type node, and then return the alignment
459 needed for the type storage in bytes.
460
461 XXX may need arch-dependent attention. */
462
463 ssize_t
464 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
465 {
466 const ctf_type_t *tp;
467 ctf_file_t *ofp = fp;
468 int kind;
469
470 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
471 return -1; /* errno is set for us. */
472
473 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
474 return -1; /* errno is set for us. */
475
476 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
477 switch (kind)
478 {
479 case CTF_K_POINTER:
480 case CTF_K_FUNCTION:
481 return fp->ctf_dmodel->ctd_pointer;
482
483 case CTF_K_ARRAY:
484 {
485 ctf_arinfo_t r;
486 if (ctf_array_info (fp, type, &r) < 0)
487 return -1; /* errno is set for us. */
488 return (ctf_type_align (fp, r.ctr_contents));
489 }
490
491 case CTF_K_STRUCT:
492 case CTF_K_UNION:
493 {
494 size_t align = 0;
495 ctf_dtdef_t *dtd;
496
497 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
498 {
499 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
500 ssize_t size, increment;
501 const void *vmp;
502
503 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
504 vmp = (unsigned char *) tp + increment;
505
506 if (kind == CTF_K_STRUCT)
507 n = MIN (n, 1); /* Only use first member for structs. */
508
509 if (size < CTF_LSTRUCT_THRESH)
510 {
511 const ctf_member_t *mp = vmp;
512 for (; n != 0; n--, mp++)
513 {
514 ssize_t am = ctf_type_align (fp, mp->ctm_type);
515 align = MAX (align, (size_t) am);
516 }
517 }
518 else
519 {
520 const ctf_lmember_t *lmp = vmp;
521 for (; n != 0; n--, lmp++)
522 {
523 ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
524 align = MAX (align, (size_t) am);
525 }
526 }
527 }
528 else
529 {
530 ctf_dmdef_t *dmd;
531
532 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
533 dmd != NULL; dmd = ctf_list_next (dmd))
534 {
535 ssize_t am = ctf_type_align (fp, dmd->dmd_type);
536 align = MAX (align, (size_t) am);
537 if (kind == CTF_K_STRUCT)
538 break;
539 }
540 }
541
542 return align;
543 }
544
545 case CTF_K_ENUM:
546 return fp->ctf_dmodel->ctd_int;
547
548 default: /* including slices of enums, etc */
549 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
550 }
551 }
552
553 /* Return the kind (CTF_K_* constant) for the specified type ID. */
554
555 int
556 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
557 {
558 const ctf_type_t *tp;
559
560 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
561 return -1; /* errno is set for us. */
562
563 return (LCTF_INFO_KIND (fp, tp->ctt_info));
564 }
565
566 /* Return the kind (CTF_K_* constant) for the specified type ID.
567 Slices are considered to be of the same kind as the type sliced. */
568
569 int
570 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
571 {
572 int kind;
573
574 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
575 return -1;
576
577 if (kind == CTF_K_SLICE)
578 {
579 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
580 return -1;
581 kind = ctf_type_kind_unsliced (fp, type);
582 }
583
584 return kind;
585 }
586
587 /* If the type is one that directly references another type (such as POINTER),
588 then return the ID of the type to which it refers. */
589
590 ctf_id_t
591 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
592 {
593 ctf_file_t *ofp = fp;
594 const ctf_type_t *tp;
595
596 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
597 return CTF_ERR; /* errno is set for us. */
598
599 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
600 {
601 case CTF_K_POINTER:
602 case CTF_K_TYPEDEF:
603 case CTF_K_VOLATILE:
604 case CTF_K_CONST:
605 case CTF_K_RESTRICT:
606 return tp->ctt_type;
607 /* Slices store their type in an unusual place. */
608 case CTF_K_SLICE:
609 {
610 const ctf_slice_t *sp;
611 ssize_t increment;
612 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
613 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
614 return sp->cts_type;
615 }
616 default:
617 return (ctf_set_errno (ofp, ECTF_NOTREF));
618 }
619 }
620
621 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
622 pointer to the given type, see if we can compute a pointer to the type
623 resulting from resolving the type down to its base type and use that
624 instead. This helps with cases where the CTF data includes "struct foo *"
625 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
626
627 XXX what about parent containers? */
628
629 ctf_id_t
630 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
631 {
632 ctf_file_t *ofp = fp;
633 ctf_id_t ntype;
634
635 if (ctf_lookup_by_id (&fp, type) == NULL)
636 return CTF_ERR; /* errno is set for us. */
637
638 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
639 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
640
641 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
642 return (ctf_set_errno (ofp, ECTF_NOTYPE));
643
644 if (ctf_lookup_by_id (&fp, type) == NULL)
645 return (ctf_set_errno (ofp, ECTF_NOTYPE));
646
647 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
648 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
649
650 return (ctf_set_errno (ofp, ECTF_NOTYPE));
651 }
652
653 /* Return the encoding for the specified INTEGER or FLOAT. */
654
655 int
656 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
657 {
658 ctf_file_t *ofp = fp;
659 ctf_dtdef_t *dtd;
660 const ctf_type_t *tp;
661 ssize_t increment;
662 uint32_t data;
663
664 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
665 return -1; /* errno is set for us. */
666
667 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
668 {
669 *ep = dtd->dtd_u.dtu_enc;
670 return 0;
671 }
672
673 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
674
675 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
676 {
677 case CTF_K_INTEGER:
678 data = *(const uint32_t *) ((uintptr_t) tp + increment);
679 ep->cte_format = CTF_INT_ENCODING (data);
680 ep->cte_offset = CTF_INT_OFFSET (data);
681 ep->cte_bits = CTF_INT_BITS (data);
682 break;
683 case CTF_K_FLOAT:
684 data = *(const uint32_t *) ((uintptr_t) tp + increment);
685 ep->cte_format = CTF_FP_ENCODING (data);
686 ep->cte_offset = CTF_FP_OFFSET (data);
687 ep->cte_bits = CTF_FP_BITS (data);
688 break;
689 case CTF_K_SLICE:
690 {
691 const ctf_slice_t *slice;
692 ctf_encoding_t underlying_en;
693
694 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
695 data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
696
697 ep->cte_format = underlying_en.cte_format;
698 ep->cte_offset = slice->cts_offset;
699 ep->cte_bits = slice->cts_bits;
700 break;
701 }
702 default:
703 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
704 }
705
706 return 0;
707 }
708
709 int
710 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
711 ctf_id_t rtype)
712 {
713 int rval;
714
715 if (ltype < rtype)
716 rval = -1;
717 else if (ltype > rtype)
718 rval = 1;
719 else
720 rval = 0;
721
722 if (lfp == rfp)
723 return rval;
724
725 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
726 lfp = lfp->ctf_parent;
727
728 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
729 rfp = rfp->ctf_parent;
730
731 if (lfp < rfp)
732 return -1;
733
734 if (lfp > rfp)
735 return 1;
736
737 return rval;
738 }
739
740 /* Return a boolean value indicating if two types are compatible. This function
741 returns true if the two types are the same, or if they (or their ultimate
742 base type) have the same encoding properties, or (for structs / unions /
743 enums / forward declarations) if they have the same name and (for structs /
744 unions) member count. */
745
746 int
747 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
748 ctf_file_t *rfp, ctf_id_t rtype)
749 {
750 const ctf_type_t *ltp, *rtp;
751 ctf_encoding_t le, re;
752 ctf_arinfo_t la, ra;
753 uint32_t lkind, rkind;
754 int same_names = 0;
755
756 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
757 return 1;
758
759 ltype = ctf_type_resolve (lfp, ltype);
760 lkind = ctf_type_kind (lfp, ltype);
761
762 rtype = ctf_type_resolve (rfp, rtype);
763 rkind = ctf_type_kind (rfp, rtype);
764
765 ltp = ctf_lookup_by_id (&lfp, ltype);
766 rtp = ctf_lookup_by_id (&rfp, rtype);
767
768 if (ltp != NULL && rtp != NULL)
769 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
770 ctf_strptr (rfp, rtp->ctt_name)) == 0);
771
772 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
773 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
774 return 1;
775
776 if (lkind != rkind)
777 return 0;
778
779 switch (lkind)
780 {
781 case CTF_K_INTEGER:
782 case CTF_K_FLOAT:
783 memset (&le, 0, sizeof (le));
784 memset (&re, 0, sizeof (re));
785 return (ctf_type_encoding (lfp, ltype, &le) == 0
786 && ctf_type_encoding (rfp, rtype, &re) == 0
787 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
788 case CTF_K_POINTER:
789 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
790 rfp, ctf_type_reference (rfp, rtype)));
791 case CTF_K_ARRAY:
792 return (ctf_array_info (lfp, ltype, &la) == 0
793 && ctf_array_info (rfp, rtype, &ra) == 0
794 && la.ctr_nelems == ra.ctr_nelems
795 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
796 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
797 case CTF_K_STRUCT:
798 case CTF_K_UNION:
799 return (same_names && (ctf_type_size (lfp, ltype)
800 == ctf_type_size (rfp, rtype)));
801 case CTF_K_ENUM:
802 {
803 int lencoded, rencoded;
804 lencoded = ctf_type_encoding (lfp, ltype, &le);
805 rencoded = ctf_type_encoding (rfp, rtype, &re);
806
807 if ((lencoded != rencoded) ||
808 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
809 return 0;
810 }
811 /* FALLTHRU */
812 case CTF_K_FORWARD:
813 return same_names; /* No other checks required for these type kinds. */
814 default:
815 return 0; /* Should not get here since we did a resolve. */
816 }
817 }
818
819 /* Return the type and offset for a given member of a STRUCT or UNION. */
820
821 int
822 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
823 ctf_membinfo_t *mip)
824 {
825 ctf_file_t *ofp = fp;
826 const ctf_type_t *tp;
827 ssize_t size, increment;
828 uint32_t kind, n;
829
830 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
831 return -1; /* errno is set for us. */
832
833 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
834 return -1; /* errno is set for us. */
835
836 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
837 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
838
839 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
840 return (ctf_set_errno (ofp, ECTF_NOTSOU));
841
842 if (size < CTF_LSTRUCT_THRESH)
843 {
844 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
845 increment);
846
847 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
848 {
849 if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
850 {
851 mip->ctm_type = mp->ctm_type;
852 mip->ctm_offset = mp->ctm_offset;
853 return 0;
854 }
855 }
856 }
857 else
858 {
859 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
860 increment);
861
862 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
863 {
864 if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
865 {
866 mip->ctm_type = lmp->ctlm_type;
867 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
868 return 0;
869 }
870 }
871 }
872
873 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
874 }
875
876 /* Return the array type, index, and size information for the specified ARRAY. */
877
878 int
879 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
880 {
881 ctf_file_t *ofp = fp;
882 const ctf_type_t *tp;
883 const ctf_array_t *ap;
884 const ctf_dtdef_t *dtd;
885 ssize_t increment;
886
887 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
888 return -1; /* errno is set for us. */
889
890 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
891 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
892
893 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
894 {
895 *arp = dtd->dtd_u.dtu_arr;
896 return 0;
897 }
898
899 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
900
901 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
902 arp->ctr_contents = ap->cta_contents;
903 arp->ctr_index = ap->cta_index;
904 arp->ctr_nelems = ap->cta_nelems;
905
906 return 0;
907 }
908
909 /* Convert the specified value to the corresponding enum tag name, if a
910 matching name can be found. Otherwise NULL is returned. */
911
912 const char *
913 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
914 {
915 ctf_file_t *ofp = fp;
916 const ctf_type_t *tp;
917 const ctf_enum_t *ep;
918 ssize_t increment;
919 uint32_t n;
920
921 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
922 return NULL; /* errno is set for us. */
923
924 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
925 return NULL; /* errno is set for us. */
926
927 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
928 {
929 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
930 return NULL;
931 }
932
933 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
934
935 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
936
937 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
938 {
939 if (ep->cte_value == value)
940 return (ctf_strptr (fp, ep->cte_name));
941 }
942
943 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
944 return NULL;
945 }
946
947 /* Convert the specified enum tag name to the corresponding value, if a
948 matching name can be found. Otherwise CTF_ERR is returned. */
949
950 int
951 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
952 {
953 ctf_file_t *ofp = fp;
954 const ctf_type_t *tp;
955 const ctf_enum_t *ep;
956 ssize_t increment;
957 uint32_t n;
958
959 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
960 return -1; /* errno is set for us. */
961
962 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
963 return -1; /* errno is set for us. */
964
965 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
966 {
967 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
968 return -1;
969 }
970
971 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
972
973 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
974
975 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
976 {
977 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
978 {
979 if (valp != NULL)
980 *valp = ep->cte_value;
981 return 0;
982 }
983 }
984
985 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
986 return -1;
987 }
988
989 /* Given a type ID relating to a function type, return info on return types and
990 arg counts for that function. */
991
992 int
993 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
994 {
995 const ctf_type_t *tp;
996 uint32_t kind;
997 const uint32_t *args;
998 ssize_t size, increment;
999
1000 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1001 return -1; /* errno is set for us. */
1002
1003 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1004 return -1; /* errno is set for us. */
1005
1006 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1007 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1008
1009 if (kind != CTF_K_FUNCTION)
1010 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1011
1012 fip->ctc_return = tp->ctt_type;
1013 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1014 fip->ctc_flags = 0;
1015
1016 args = (uint32_t *) ((uintptr_t) tp + increment);
1017
1018 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1019 {
1020 fip->ctc_flags |= CTF_FUNC_VARARG;
1021 fip->ctc_argc--;
1022 }
1023
1024 return 0;
1025 }
1026
1027 /* Given a type ID relating to a function type,, return the arguments for the
1028 function. */
1029
1030 int
1031 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1032 {
1033 const ctf_type_t *tp;
1034 const uint32_t *args;
1035 ssize_t size, increment;
1036 ctf_funcinfo_t f;
1037
1038 if (ctf_func_type_info (fp, type, &f) < 0)
1039 return -1; /* errno is set for us. */
1040
1041 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1042 return -1; /* errno is set for us. */
1043
1044 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1045 return -1; /* errno is set for us. */
1046
1047 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1048
1049 args = (uint32_t *) ((uintptr_t) tp + increment);
1050
1051 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1052 *argv++ = *args++;
1053
1054 return 0;
1055 }
1056
1057 /* Recursively visit the members of any type. This function is used as the
1058 engine for ctf_type_visit, below. We resolve the input type, recursively
1059 invoke ourself for each type member if the type is a struct or union, and
1060 then invoke the callback function on the current type. If any callback
1061 returns non-zero, we abort and percolate the error code back up to the top. */
1062
1063 static int
1064 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1065 void *arg, const char *name, unsigned long offset, int depth)
1066 {
1067 ctf_id_t otype = type;
1068 const ctf_type_t *tp;
1069 ssize_t size, increment;
1070 uint32_t kind, n;
1071 int rc;
1072
1073 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1074 return -1; /* errno is set for us. */
1075
1076 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1077 return -1; /* errno is set for us. */
1078
1079 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1080 return rc;
1081
1082 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1083
1084 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1085 return 0;
1086
1087 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1088
1089 if (size < CTF_LSTRUCT_THRESH)
1090 {
1091 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1092 increment);
1093
1094 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1095 {
1096 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1097 func, arg, ctf_strptr (fp, mp->ctm_name),
1098 offset + mp->ctm_offset,
1099 depth + 1)) != 0)
1100 return rc;
1101 }
1102
1103 }
1104 else
1105 {
1106 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1107 increment);
1108
1109 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1110 {
1111 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1112 func, arg, ctf_strptr (fp,
1113 lmp->ctlm_name),
1114 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1115 depth + 1)) != 0)
1116 return rc;
1117 }
1118 }
1119
1120 return 0;
1121 }
1122
1123 /* Recursively visit the members of any type. We pass the name, member
1124 type, and offset of each member to the specified callback function. */
1125 int
1126 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1127 {
1128 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1129 }
This page took 0.052711 seconds and 4 git commands to generate.