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