libctf: properly handle ctf_add_type of forwards and self-reffing structs
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
1 /* Type handling functions.
2 Copyright (C) 2019 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20 #include <ctf-impl.h>
21 #include <string.h>
22
23 /* Determine whether a type is a parent or a child. */
24
25 int
26 ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27 {
28 return (LCTF_TYPE_ISPARENT (fp, id));
29 }
30
31 int
32 ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33 {
34 return (LCTF_TYPE_ISCHILD (fp, id));
35 }
36
37 /* Iterate over the members of a STRUCT or UNION. We pass the name, member
38 type, and offset of each member to the specified callback function. */
39
40 int
41 ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42 {
43 ctf_file_t *ofp = fp;
44 const ctf_type_t *tp;
45 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 = strlen (str);
442
443 if (str == NULL)
444 return CTF_ERR; /* errno is set for us */
445
446 snprintf (buf, len, "%s", str);
447 free (str);
448
449 if (slen >= len)
450 (void) ctf_set_errno (fp, ECTF_NAMELEN);
451
452 return slen;
453 }
454
455 /* Lookup the given type ID and print a string name for it into buf. If buf
456 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
457
458 char *
459 ctf_type_name (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
460 {
461 ssize_t rv = ctf_type_lname (fp, type, buf, len);
462 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
463 }
464
465 /* Lookup the given type ID and return its raw, unadorned, undecorated name as a
466 new dynamcally-allocated string. */
467
468 char *
469 ctf_type_aname_raw (ctf_file_t *fp, ctf_id_t type)
470 {
471 const ctf_type_t *tp;
472
473 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
474 return NULL; /* errno is set for us. */
475
476 if (ctf_strraw (fp, tp->ctt_name) != NULL)
477 return strdup (ctf_strraw (fp, tp->ctt_name));
478
479 return NULL;
480 }
481
482 /* Resolve the type down to a base type node, and then return the size
483 of the type storage in bytes. */
484
485 ssize_t
486 ctf_type_size (ctf_file_t *fp, ctf_id_t type)
487 {
488 const ctf_type_t *tp;
489 ssize_t size;
490 ctf_arinfo_t ar;
491
492 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
493 return -1; /* errno is set for us. */
494
495 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
496 return -1; /* errno is set for us. */
497
498 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
499 {
500 case CTF_K_POINTER:
501 return fp->ctf_dmodel->ctd_pointer;
502
503 case CTF_K_FUNCTION:
504 return 0; /* Function size is only known by symtab. */
505
506 case CTF_K_ENUM:
507 return fp->ctf_dmodel->ctd_int;
508
509 case CTF_K_ARRAY:
510 /* ctf_add_array() does not directly encode the element size, but
511 requires the user to multiply to determine the element size.
512
513 If ctf_get_ctt_size() returns nonzero, then use the recorded
514 size instead. */
515
516 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
517 return size;
518
519 if (ctf_array_info (fp, type, &ar) < 0
520 || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
521 return -1; /* errno is set for us. */
522
523 return size * ar.ctr_nelems;
524
525 default: /* including slices of enums, etc */
526 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
527 }
528 }
529
530 /* Resolve the type down to a base type node, and then return the alignment
531 needed for the type storage in bytes.
532
533 XXX may need arch-dependent attention. */
534
535 ssize_t
536 ctf_type_align (ctf_file_t *fp, ctf_id_t type)
537 {
538 const ctf_type_t *tp;
539 ctf_file_t *ofp = fp;
540 int kind;
541
542 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
543 return -1; /* errno is set for us. */
544
545 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
546 return -1; /* errno is set for us. */
547
548 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
549 switch (kind)
550 {
551 case CTF_K_POINTER:
552 case CTF_K_FUNCTION:
553 return fp->ctf_dmodel->ctd_pointer;
554
555 case CTF_K_ARRAY:
556 {
557 ctf_arinfo_t r;
558 if (ctf_array_info (fp, type, &r) < 0)
559 return -1; /* errno is set for us. */
560 return (ctf_type_align (fp, r.ctr_contents));
561 }
562
563 case CTF_K_STRUCT:
564 case CTF_K_UNION:
565 {
566 size_t align = 0;
567 ctf_dtdef_t *dtd;
568
569 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
570 {
571 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
572 ssize_t size, increment;
573 const void *vmp;
574
575 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
576 vmp = (unsigned char *) tp + increment;
577
578 if (kind == CTF_K_STRUCT)
579 n = MIN (n, 1); /* Only use first member for structs. */
580
581 if (size < CTF_LSTRUCT_THRESH)
582 {
583 const ctf_member_t *mp = vmp;
584 for (; n != 0; n--, mp++)
585 {
586 ssize_t am = ctf_type_align (fp, mp->ctm_type);
587 align = MAX (align, (size_t) am);
588 }
589 }
590 else
591 {
592 const ctf_lmember_t *lmp = vmp;
593 for (; n != 0; n--, lmp++)
594 {
595 ssize_t am = ctf_type_align (fp, lmp->ctlm_type);
596 align = MAX (align, (size_t) am);
597 }
598 }
599 }
600 else
601 {
602 ctf_dmdef_t *dmd;
603
604 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
605 dmd != NULL; dmd = ctf_list_next (dmd))
606 {
607 ssize_t am = ctf_type_align (fp, dmd->dmd_type);
608 align = MAX (align, (size_t) am);
609 if (kind == CTF_K_STRUCT)
610 break;
611 }
612 }
613
614 return align;
615 }
616
617 case CTF_K_ENUM:
618 return fp->ctf_dmodel->ctd_int;
619
620 default: /* including slices of enums, etc */
621 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
622 }
623 }
624
625 /* Return the kind (CTF_K_* constant) for the specified type ID. */
626
627 int
628 ctf_type_kind_unsliced (ctf_file_t *fp, ctf_id_t type)
629 {
630 const ctf_type_t *tp;
631
632 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
633 return -1; /* errno is set for us. */
634
635 return (LCTF_INFO_KIND (fp, tp->ctt_info));
636 }
637
638 /* Return the kind (CTF_K_* constant) for the specified type ID.
639 Slices are considered to be of the same kind as the type sliced. */
640
641 int
642 ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
643 {
644 int kind;
645
646 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
647 return -1;
648
649 if (kind == CTF_K_SLICE)
650 {
651 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
652 return -1;
653 kind = ctf_type_kind_unsliced (fp, type);
654 }
655
656 return kind;
657 }
658
659 /* If the type is one that directly references another type (such as POINTER),
660 then return the ID of the type to which it refers. */
661
662 ctf_id_t
663 ctf_type_reference (ctf_file_t *fp, ctf_id_t type)
664 {
665 ctf_file_t *ofp = fp;
666 const ctf_type_t *tp;
667
668 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
669 return CTF_ERR; /* errno is set for us. */
670
671 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
672 {
673 case CTF_K_POINTER:
674 case CTF_K_TYPEDEF:
675 case CTF_K_VOLATILE:
676 case CTF_K_CONST:
677 case CTF_K_RESTRICT:
678 return tp->ctt_type;
679 /* Slices store their type in an unusual place. */
680 case CTF_K_SLICE:
681 {
682 const ctf_slice_t *sp;
683 ssize_t increment;
684 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
685 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
686 return sp->cts_type;
687 }
688 default:
689 return (ctf_set_errno (ofp, ECTF_NOTREF));
690 }
691 }
692
693 /* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
694 pointer to the given type, see if we can compute a pointer to the type
695 resulting from resolving the type down to its base type and use that
696 instead. This helps with cases where the CTF data includes "struct foo *"
697 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
698
699 XXX what about parent containers? */
700
701 ctf_id_t
702 ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
703 {
704 ctf_file_t *ofp = fp;
705 ctf_id_t ntype;
706
707 if (ctf_lookup_by_id (&fp, type) == NULL)
708 return CTF_ERR; /* errno is set for us. */
709
710 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
711 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
712
713 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
714 return (ctf_set_errno (ofp, ECTF_NOTYPE));
715
716 if (ctf_lookup_by_id (&fp, type) == NULL)
717 return (ctf_set_errno (ofp, ECTF_NOTYPE));
718
719 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
720 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
721
722 return (ctf_set_errno (ofp, ECTF_NOTYPE));
723 }
724
725 /* Return the encoding for the specified INTEGER or FLOAT. */
726
727 int
728 ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
729 {
730 ctf_file_t *ofp = fp;
731 ctf_dtdef_t *dtd;
732 const ctf_type_t *tp;
733 ssize_t increment;
734 uint32_t data;
735
736 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
737 return -1; /* errno is set for us. */
738
739 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
740 {
741 *ep = dtd->dtd_u.dtu_enc;
742 return 0;
743 }
744
745 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
746
747 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
748 {
749 case CTF_K_INTEGER:
750 data = *(const uint32_t *) ((uintptr_t) tp + increment);
751 ep->cte_format = CTF_INT_ENCODING (data);
752 ep->cte_offset = CTF_INT_OFFSET (data);
753 ep->cte_bits = CTF_INT_BITS (data);
754 break;
755 case CTF_K_FLOAT:
756 data = *(const uint32_t *) ((uintptr_t) tp + increment);
757 ep->cte_format = CTF_FP_ENCODING (data);
758 ep->cte_offset = CTF_FP_OFFSET (data);
759 ep->cte_bits = CTF_FP_BITS (data);
760 break;
761 case CTF_K_SLICE:
762 {
763 const ctf_slice_t *slice;
764 ctf_encoding_t underlying_en;
765
766 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
767 data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
768
769 ep->cte_format = underlying_en.cte_format;
770 ep->cte_offset = slice->cts_offset;
771 ep->cte_bits = slice->cts_bits;
772 break;
773 }
774 default:
775 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
776 }
777
778 return 0;
779 }
780
781 int
782 ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
783 ctf_id_t rtype)
784 {
785 int rval;
786
787 if (ltype < rtype)
788 rval = -1;
789 else if (ltype > rtype)
790 rval = 1;
791 else
792 rval = 0;
793
794 if (lfp == rfp)
795 return rval;
796
797 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
798 lfp = lfp->ctf_parent;
799
800 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
801 rfp = rfp->ctf_parent;
802
803 if (lfp < rfp)
804 return -1;
805
806 if (lfp > rfp)
807 return 1;
808
809 return rval;
810 }
811
812 /* Return a boolean value indicating if two types are compatible. This function
813 returns true if the two types are the same, or if they (or their ultimate
814 base type) have the same encoding properties, or (for structs / unions /
815 enums / forward declarations) if they have the same name and (for structs /
816 unions) member count. */
817
818 int
819 ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
820 ctf_file_t *rfp, ctf_id_t rtype)
821 {
822 const ctf_type_t *ltp, *rtp;
823 ctf_encoding_t le, re;
824 ctf_arinfo_t la, ra;
825 uint32_t lkind, rkind;
826 int same_names = 0;
827
828 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
829 return 1;
830
831 ltype = ctf_type_resolve (lfp, ltype);
832 lkind = ctf_type_kind (lfp, ltype);
833
834 rtype = ctf_type_resolve (rfp, rtype);
835 rkind = ctf_type_kind (rfp, rtype);
836
837 ltp = ctf_lookup_by_id (&lfp, ltype);
838 rtp = ctf_lookup_by_id (&rfp, rtype);
839
840 if (ltp != NULL && rtp != NULL)
841 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
842 ctf_strptr (rfp, rtp->ctt_name)) == 0);
843
844 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
845 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
846 return 1;
847
848 if (lkind != rkind)
849 return 0;
850
851 switch (lkind)
852 {
853 case CTF_K_INTEGER:
854 case CTF_K_FLOAT:
855 memset (&le, 0, sizeof (le));
856 memset (&re, 0, sizeof (re));
857 return (ctf_type_encoding (lfp, ltype, &le) == 0
858 && ctf_type_encoding (rfp, rtype, &re) == 0
859 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
860 case CTF_K_POINTER:
861 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
862 rfp, ctf_type_reference (rfp, rtype)));
863 case CTF_K_ARRAY:
864 return (ctf_array_info (lfp, ltype, &la) == 0
865 && ctf_array_info (rfp, rtype, &ra) == 0
866 && la.ctr_nelems == ra.ctr_nelems
867 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
868 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
869 case CTF_K_STRUCT:
870 case CTF_K_UNION:
871 return (same_names && (ctf_type_size (lfp, ltype)
872 == ctf_type_size (rfp, rtype)));
873 case CTF_K_ENUM:
874 {
875 int lencoded, rencoded;
876 lencoded = ctf_type_encoding (lfp, ltype, &le);
877 rencoded = ctf_type_encoding (rfp, rtype, &re);
878
879 if ((lencoded != rencoded) ||
880 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
881 return 0;
882 }
883 /* FALLTHRU */
884 case CTF_K_FORWARD:
885 return same_names; /* No other checks required for these type kinds. */
886 default:
887 return 0; /* Should not get here since we did a resolve. */
888 }
889 }
890
891 /* Return the type and offset for a given member of a STRUCT or UNION. */
892
893 int
894 ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
895 ctf_membinfo_t *mip)
896 {
897 ctf_file_t *ofp = fp;
898 const ctf_type_t *tp;
899 ctf_dtdef_t *dtd;
900 ssize_t size, increment;
901 uint32_t kind, n;
902
903 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
904 return -1; /* errno is set for us. */
905
906 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
907 return -1; /* errno is set for us. */
908
909 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
910 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
911
912 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
913 return (ctf_set_errno (ofp, ECTF_NOTSOU));
914
915 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
916 {
917 if (size < CTF_LSTRUCT_THRESH)
918 {
919 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
920 increment);
921
922 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
923 {
924 if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
925 {
926 mip->ctm_type = mp->ctm_type;
927 mip->ctm_offset = mp->ctm_offset;
928 return 0;
929 }
930 }
931 }
932 else
933 {
934 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
935 increment);
936
937 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
938 {
939 if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
940 {
941 mip->ctm_type = lmp->ctlm_type;
942 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
943 return 0;
944 }
945 }
946 }
947 }
948 else
949 {
950 ctf_dmdef_t *dmd;
951
952 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
953 dmd != NULL; dmd = ctf_list_next (dmd))
954 {
955 if (strcmp (dmd->dmd_name, name) == 0)
956 {
957 mip->ctm_type = dmd->dmd_type;
958 mip->ctm_offset = dmd->dmd_offset;
959 return 0;
960 }
961 }
962 }
963
964 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
965 }
966
967 /* Return the array type, index, and size information for the specified ARRAY. */
968
969 int
970 ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
971 {
972 ctf_file_t *ofp = fp;
973 const ctf_type_t *tp;
974 const ctf_array_t *ap;
975 const ctf_dtdef_t *dtd;
976 ssize_t increment;
977
978 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
979 return -1; /* errno is set for us. */
980
981 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
982 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
983
984 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
985 {
986 *arp = dtd->dtd_u.dtu_arr;
987 return 0;
988 }
989
990 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
991
992 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
993 arp->ctr_contents = ap->cta_contents;
994 arp->ctr_index = ap->cta_index;
995 arp->ctr_nelems = ap->cta_nelems;
996
997 return 0;
998 }
999
1000 /* Convert the specified value to the corresponding enum tag name, if a
1001 matching name can be found. Otherwise NULL is returned. */
1002
1003 const char *
1004 ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1005 {
1006 ctf_file_t *ofp = fp;
1007 const ctf_type_t *tp;
1008 const ctf_enum_t *ep;
1009 const ctf_dtdef_t *dtd;
1010 ssize_t increment;
1011 uint32_t n;
1012
1013 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1014 return NULL; /* errno is set for us. */
1015
1016 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1017 return NULL; /* errno is set for us. */
1018
1019 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1020 {
1021 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1022 return NULL;
1023 }
1024
1025 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1026
1027 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1028 {
1029 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1030
1031 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1032 {
1033 if (ep->cte_value == value)
1034 return (ctf_strptr (fp, ep->cte_name));
1035 }
1036 }
1037 else
1038 {
1039 ctf_dmdef_t *dmd;
1040
1041 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1042 dmd != NULL; dmd = ctf_list_next (dmd))
1043 {
1044 if (dmd->dmd_value == value)
1045 return dmd->dmd_name;
1046 }
1047 }
1048
1049 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1050 return NULL;
1051 }
1052
1053 /* Convert the specified enum tag name to the corresponding value, if a
1054 matching name can be found. Otherwise CTF_ERR is returned. */
1055
1056 int
1057 ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1058 {
1059 ctf_file_t *ofp = fp;
1060 const ctf_type_t *tp;
1061 const ctf_enum_t *ep;
1062 const ctf_dtdef_t *dtd;
1063 ssize_t increment;
1064 uint32_t n;
1065
1066 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1067 return -1; /* errno is set for us. */
1068
1069 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1070 return -1; /* errno is set for us. */
1071
1072 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1073 {
1074 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1075 return -1;
1076 }
1077
1078 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1079
1080 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1081
1082 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1083 {
1084 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1085 {
1086 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1087 {
1088 if (valp != NULL)
1089 *valp = ep->cte_value;
1090 return 0;
1091 }
1092 }
1093 }
1094 else
1095 {
1096 ctf_dmdef_t *dmd;
1097
1098 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1099 dmd != NULL; dmd = ctf_list_next (dmd))
1100 {
1101 if (strcmp (dmd->dmd_name, name) == 0)
1102 {
1103 if (valp != NULL)
1104 *valp = dmd->dmd_value;
1105 return 0;
1106 }
1107 }
1108 }
1109
1110 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1111 return -1;
1112 }
1113
1114 /* Given a type ID relating to a function type, return info on return types and
1115 arg counts for that function. */
1116
1117 int
1118 ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1119 {
1120 const ctf_type_t *tp;
1121 uint32_t kind;
1122 const uint32_t *args;
1123 const ctf_dtdef_t *dtd;
1124 ssize_t size, increment;
1125
1126 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1127 return -1; /* errno is set for us. */
1128
1129 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1130 return -1; /* errno is set for us. */
1131
1132 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1133 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1134
1135 if (kind != CTF_K_FUNCTION)
1136 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1137
1138 fip->ctc_return = tp->ctt_type;
1139 fip->ctc_flags = 0;
1140 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
1141
1142 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1143 args = (uint32_t *) ((uintptr_t) tp + increment);
1144 else
1145 args = (uint32_t *) dtd->dtd_u.dtu_argv;
1146
1147 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1148 {
1149 fip->ctc_flags |= CTF_FUNC_VARARG;
1150 fip->ctc_argc--;
1151 }
1152
1153 return 0;
1154 }
1155
1156 /* Given a type ID relating to a function type,, return the arguments for the
1157 function. */
1158
1159 int
1160 ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1161 {
1162 const ctf_type_t *tp;
1163 const uint32_t *args;
1164 const ctf_dtdef_t *dtd;
1165 ssize_t size, increment;
1166 ctf_funcinfo_t f;
1167
1168 if (ctf_func_type_info (fp, type, &f) < 0)
1169 return -1; /* errno is set for us. */
1170
1171 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1172 return -1; /* errno is set for us. */
1173
1174 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1175 return -1; /* errno is set for us. */
1176
1177 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1178
1179 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1180 args = (uint32_t *) ((uintptr_t) tp + increment);
1181 else
1182 args = (uint32_t *) dtd->dtd_u.dtu_argv;
1183
1184 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1185 *argv++ = *args++;
1186
1187 return 0;
1188 }
1189
1190 /* Recursively visit the members of any type. This function is used as the
1191 engine for ctf_type_visit, below. We resolve the input type, recursively
1192 invoke ourself for each type member if the type is a struct or union, and
1193 then invoke the callback function on the current type. If any callback
1194 returns non-zero, we abort and percolate the error code back up to the top. */
1195
1196 static int
1197 ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1198 void *arg, const char *name, unsigned long offset, int depth)
1199 {
1200 ctf_id_t otype = type;
1201 const ctf_type_t *tp;
1202 const ctf_dtdef_t *dtd;
1203 ssize_t size, increment;
1204 uint32_t kind, n;
1205 int rc;
1206
1207 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1208 return -1; /* errno is set for us. */
1209
1210 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1211 return -1; /* errno is set for us. */
1212
1213 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1214 return rc;
1215
1216 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1217
1218 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1219 return 0;
1220
1221 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1222
1223 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1224 {
1225 if (size < CTF_LSTRUCT_THRESH)
1226 {
1227 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1228 increment);
1229
1230 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1231 {
1232 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1233 func, arg, ctf_strptr (fp,
1234 mp->ctm_name),
1235 offset + mp->ctm_offset,
1236 depth + 1)) != 0)
1237 return rc;
1238 }
1239 }
1240 else
1241 {
1242 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1243 increment);
1244
1245 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1246 {
1247 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1248 func, arg, ctf_strptr (fp,
1249 lmp->ctlm_name),
1250 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1251 depth + 1)) != 0)
1252 return rc;
1253 }
1254 }
1255 }
1256 else
1257 {
1258 ctf_dmdef_t *dmd;
1259
1260 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1261 dmd != NULL; dmd = ctf_list_next (dmd))
1262 {
1263 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1264 dmd->dmd_name, dmd->dmd_offset,
1265 depth + 1)) != 0)
1266 return rc;
1267 }
1268 }
1269
1270 return 0;
1271 }
1272
1273 /* Recursively visit the members of any type. We pass the name, member
1274 type, and offset of each member to the specified callback function. */
1275 int
1276 ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1277 {
1278 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1279 }
This page took 0.057914 seconds and 4 git commands to generate.