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