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