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