libctf: allow ctf_type_lname of a null pointer.
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
CommitLineData
316afdb1
NA
1/* Type handling functions.
2 Copyright (C) 2019 Free Software Foundation, Inc.
3
4 This file is part of libctf.
5
6 libctf is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 See the GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not see
18 <http://www.gnu.org/licenses/>. */
19
20#include <ctf-impl.h>
21#include <string.h>
22
23/* Determine whether a type is a parent or a child. */
24
25int
26ctf_type_isparent (ctf_file_t *fp, ctf_id_t id)
27{
28 return (LCTF_TYPE_ISPARENT (fp, id));
29}
30
31int
32ctf_type_ischild (ctf_file_t * fp, ctf_id_t id)
33{
34 return (LCTF_TYPE_ISCHILD (fp, id));
35}
36
37/* Iterate over the members of a STRUCT or UNION. We pass the name, member
38 type, and offset of each member to the specified callback function. */
39
40int
41ctf_member_iter (ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
42{
43 ctf_file_t *ofp = fp;
44 const ctf_type_t *tp;
676c3ecb 45 ctf_dtdef_t *dtd;
316afdb1
NA
46 ssize_t size, increment;
47 uint32_t kind, n;
48 int rc;
49
50 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 51 return -1; /* errno is set for us. */
316afdb1
NA
52
53 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 54 return -1; /* errno is set for us. */
316afdb1
NA
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
676c3ecb 62 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
316afdb1 63 {
676c3ecb 64 if (size < CTF_LSTRUCT_THRESH)
316afdb1 65 {
676c3ecb
NA
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)
316afdb1 73 return rc;
676c3ecb 74 }
316afdb1 75 }
676c3ecb
NA
76 else
77 {
78 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
79 increment);
316afdb1 80
676c3ecb
NA
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 }
316afdb1
NA
89 }
90 else
91 {
676c3ecb 92 ctf_dmdef_t *dmd;
316afdb1 93
676c3ecb
NA
94 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
95 dmd != NULL; dmd = ctf_list_next (dmd))
316afdb1 96 {
676c3ecb
NA
97 if ((rc = func (dmd->dmd_name, dmd->dmd_type,
98 dmd->dmd_offset, arg)) != 0)
316afdb1
NA
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
109int
110ctf_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;
676c3ecb 115 ctf_dtdef_t *dtd;
316afdb1
NA
116 ssize_t increment;
117 uint32_t n;
118 int rc;
119
120 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
a0486bac 121 return -1; /* errno is set for us. */
316afdb1
NA
122
123 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 124 return -1; /* errno is set for us. */
316afdb1
NA
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
676c3ecb
NA
131 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
132 {
133 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
316afdb1 134
676c3ecb
NA
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
316afdb1 143 {
676c3ecb
NA
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 }
316afdb1
NA
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
160int
161ctf_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
0ac62312
NA
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
180int
181ctf_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
316afdb1
NA
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
201int
202ctf_variable_iter (ctf_file_t *fp, ctf_variable_f *func, void *arg)
203{
316afdb1
NA
204 int rc;
205
206 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
207 return ECTF_NOPARENT;
208
676c3ecb
NA
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 }
316afdb1
NA
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
240ctf_id_t
241ctf_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
791915db
NA
247 if (type == 0)
248 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
249
316afdb1
NA
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 }
791915db
NA
270 if (type == 0)
271 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
316afdb1
NA
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
280ctf_id_t
281ctf_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
676c3ecb
NA
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
299ctf_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
308ctf_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
316afdb1
NA
319/* Lookup the given type ID and return its name as a new dynamcally-allocated
320 string. */
321
322char *
323ctf_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
437ssize_t
438ctf_type_lname (ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
439{
440 char *str = ctf_type_aname (fp, type);
1a6ab13e 441 size_t slen;
316afdb1
NA
442
443 if (str == NULL)
444 return CTF_ERR; /* errno is set for us */
445
1a6ab13e 446 slen = strlen (str);
316afdb1
NA
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
459char *
460ctf_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
12a0b67d
NA
466/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
467 new dynamcally-allocated string. */
468
469char *
470ctf_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
316afdb1
NA
483/* Resolve the type down to a base type node, and then return the size
484 of the type storage in bytes. */
485
486ssize_t
487ctf_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
a0486bac
JM
520 if (ctf_array_info (fp, type, &ar) < 0
521 || (size = ctf_type_size (fp, ar.ctr_contents)) < 0)
316afdb1
NA
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
536ssize_t
537ctf_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;
a0486bac 559 if (ctf_array_info (fp, type, &r) < 0)
316afdb1
NA
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);
a0486bac 588 align = MAX (align, (size_t) am);
316afdb1
NA
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);
a0486bac 597 align = MAX (align, (size_t) am);
316afdb1
NA
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);
a0486bac 609 align = MAX (align, (size_t) am);
316afdb1
NA
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
628int
629ctf_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)
a0486bac 634 return -1; /* errno is set for us. */
316afdb1
NA
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
642int
643ctf_type_kind (ctf_file_t *fp, ctf_id_t type)
644{
645 int kind;
646
a0486bac
JM
647 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
648 return -1;
316afdb1
NA
649
650 if (kind == CTF_K_SLICE)
651 {
652 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
a0486bac 653 return -1;
316afdb1
NA
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
663ctf_id_t
664ctf_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 const ctf_slice_t *sp;
684 ssize_t increment;
685 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
686 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
687 return sp->cts_type;
688 }
689 default:
690 return (ctf_set_errno (ofp, ECTF_NOTREF));
691 }
692}
693
694/* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
695 pointer to the given type, see if we can compute a pointer to the type
696 resulting from resolving the type down to its base type and use that
697 instead. This helps with cases where the CTF data includes "struct foo *"
698 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
699
700 XXX what about parent containers? */
701
702ctf_id_t
703ctf_type_pointer (ctf_file_t *fp, ctf_id_t type)
704{
705 ctf_file_t *ofp = fp;
706 ctf_id_t ntype;
707
708 if (ctf_lookup_by_id (&fp, type) == NULL)
709 return CTF_ERR; /* errno is set for us. */
710
711 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
712 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
713
714 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
715 return (ctf_set_errno (ofp, ECTF_NOTYPE));
716
717 if (ctf_lookup_by_id (&fp, type) == NULL)
718 return (ctf_set_errno (ofp, ECTF_NOTYPE));
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 return (ctf_set_errno (ofp, ECTF_NOTYPE));
724}
725
726/* Return the encoding for the specified INTEGER or FLOAT. */
727
728int
729ctf_type_encoding (ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
730{
731 ctf_file_t *ofp = fp;
732 ctf_dtdef_t *dtd;
733 const ctf_type_t *tp;
734 ssize_t increment;
735 uint32_t data;
736
737 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 738 return -1; /* errno is set for us. */
316afdb1
NA
739
740 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
741 {
742 *ep = dtd->dtd_u.dtu_enc;
743 return 0;
744 }
745
746 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
747
748 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
749 {
750 case CTF_K_INTEGER:
751 data = *(const uint32_t *) ((uintptr_t) tp + increment);
752 ep->cte_format = CTF_INT_ENCODING (data);
753 ep->cte_offset = CTF_INT_OFFSET (data);
754 ep->cte_bits = CTF_INT_BITS (data);
755 break;
756 case CTF_K_FLOAT:
757 data = *(const uint32_t *) ((uintptr_t) tp + increment);
758 ep->cte_format = CTF_FP_ENCODING (data);
759 ep->cte_offset = CTF_FP_OFFSET (data);
760 ep->cte_bits = CTF_FP_BITS (data);
761 break;
762 case CTF_K_SLICE:
763 {
764 const ctf_slice_t *slice;
765 ctf_encoding_t underlying_en;
766
767 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
768 data = ctf_type_encoding (fp, slice->cts_type, &underlying_en);
769
770 ep->cte_format = underlying_en.cte_format;
771 ep->cte_offset = slice->cts_offset;
772 ep->cte_bits = slice->cts_bits;
773 break;
774 }
775 default:
776 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
777 }
778
779 return 0;
780}
781
782int
783ctf_type_cmp (ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp,
784 ctf_id_t rtype)
785{
786 int rval;
787
788 if (ltype < rtype)
789 rval = -1;
790 else if (ltype > rtype)
791 rval = 1;
792 else
793 rval = 0;
794
795 if (lfp == rfp)
796 return rval;
797
798 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
799 lfp = lfp->ctf_parent;
800
801 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
802 rfp = rfp->ctf_parent;
803
804 if (lfp < rfp)
805 return -1;
806
807 if (lfp > rfp)
808 return 1;
809
810 return rval;
811}
812
813/* Return a boolean value indicating if two types are compatible. This function
814 returns true if the two types are the same, or if they (or their ultimate
815 base type) have the same encoding properties, or (for structs / unions /
816 enums / forward declarations) if they have the same name and (for structs /
817 unions) member count. */
818
819int
820ctf_type_compat (ctf_file_t *lfp, ctf_id_t ltype,
821 ctf_file_t *rfp, ctf_id_t rtype)
822{
823 const ctf_type_t *ltp, *rtp;
824 ctf_encoding_t le, re;
825 ctf_arinfo_t la, ra;
826 uint32_t lkind, rkind;
827 int same_names = 0;
828
829 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
830 return 1;
831
832 ltype = ctf_type_resolve (lfp, ltype);
833 lkind = ctf_type_kind (lfp, ltype);
834
835 rtype = ctf_type_resolve (rfp, rtype);
836 rkind = ctf_type_kind (rfp, rtype);
837
838 ltp = ctf_lookup_by_id (&lfp, ltype);
839 rtp = ctf_lookup_by_id (&rfp, rtype);
840
841 if (ltp != NULL && rtp != NULL)
842 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
843 ctf_strptr (rfp, rtp->ctt_name)) == 0);
844
845 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
846 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
847 return 1;
848
849 if (lkind != rkind)
850 return 0;
851
852 switch (lkind)
853 {
854 case CTF_K_INTEGER:
855 case CTF_K_FLOAT:
856 memset (&le, 0, sizeof (le));
857 memset (&re, 0, sizeof (re));
858 return (ctf_type_encoding (lfp, ltype, &le) == 0
859 && ctf_type_encoding (rfp, rtype, &re) == 0
860 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
861 case CTF_K_POINTER:
862 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
863 rfp, ctf_type_reference (rfp, rtype)));
864 case CTF_K_ARRAY:
865 return (ctf_array_info (lfp, ltype, &la) == 0
866 && ctf_array_info (rfp, rtype, &ra) == 0
867 && la.ctr_nelems == ra.ctr_nelems
868 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
869 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
870 case CTF_K_STRUCT:
871 case CTF_K_UNION:
872 return (same_names && (ctf_type_size (lfp, ltype)
873 == ctf_type_size (rfp, rtype)));
874 case CTF_K_ENUM:
875 {
876 int lencoded, rencoded;
877 lencoded = ctf_type_encoding (lfp, ltype, &le);
878 rencoded = ctf_type_encoding (rfp, rtype, &re);
879
880 if ((lencoded != rencoded) ||
881 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
882 return 0;
883 }
884 /* FALLTHRU */
885 case CTF_K_FORWARD:
886 return same_names; /* No other checks required for these type kinds. */
887 default:
888 return 0; /* Should not get here since we did a resolve. */
889 }
890}
891
892/* Return the type and offset for a given member of a STRUCT or UNION. */
893
894int
895ctf_member_info (ctf_file_t *fp, ctf_id_t type, const char *name,
896 ctf_membinfo_t *mip)
897{
898 ctf_file_t *ofp = fp;
899 const ctf_type_t *tp;
676c3ecb 900 ctf_dtdef_t *dtd;
316afdb1
NA
901 ssize_t size, increment;
902 uint32_t kind, n;
903
904 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 905 return -1; /* errno is set for us. */
316afdb1
NA
906
907 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 908 return -1; /* errno is set for us. */
316afdb1
NA
909
910 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
911 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
912
913 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
914 return (ctf_set_errno (ofp, ECTF_NOTSOU));
915
676c3ecb 916 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
316afdb1 917 {
676c3ecb
NA
918 if (size < CTF_LSTRUCT_THRESH)
919 {
920 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
921 increment);
316afdb1 922
676c3ecb
NA
923 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
924 {
925 if (strcmp (ctf_strptr (fp, mp->ctm_name), name) == 0)
926 {
927 mip->ctm_type = mp->ctm_type;
928 mip->ctm_offset = mp->ctm_offset;
929 return 0;
930 }
931 }
932 }
933 else
316afdb1 934 {
676c3ecb
NA
935 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
936 increment);
937
938 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
316afdb1 939 {
676c3ecb
NA
940 if (strcmp (ctf_strptr (fp, lmp->ctlm_name), name) == 0)
941 {
942 mip->ctm_type = lmp->ctlm_type;
943 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
944 return 0;
945 }
316afdb1
NA
946 }
947 }
948 }
949 else
950 {
676c3ecb 951 ctf_dmdef_t *dmd;
316afdb1 952
676c3ecb
NA
953 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
954 dmd != NULL; dmd = ctf_list_next (dmd))
316afdb1 955 {
676c3ecb 956 if (strcmp (dmd->dmd_name, name) == 0)
316afdb1 957 {
676c3ecb
NA
958 mip->ctm_type = dmd->dmd_type;
959 mip->ctm_offset = dmd->dmd_offset;
316afdb1
NA
960 return 0;
961 }
962 }
963 }
964
965 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
966}
967
968/* Return the array type, index, and size information for the specified ARRAY. */
969
970int
971ctf_array_info (ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
972{
973 ctf_file_t *ofp = fp;
974 const ctf_type_t *tp;
975 const ctf_array_t *ap;
976 const ctf_dtdef_t *dtd;
977 ssize_t increment;
978
979 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 980 return -1; /* errno is set for us. */
316afdb1
NA
981
982 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
983 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
984
985 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
986 {
987 *arp = dtd->dtd_u.dtu_arr;
988 return 0;
989 }
990
991 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
992
993 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
994 arp->ctr_contents = ap->cta_contents;
995 arp->ctr_index = ap->cta_index;
996 arp->ctr_nelems = ap->cta_nelems;
997
998 return 0;
999}
1000
1001/* Convert the specified value to the corresponding enum tag name, if a
1002 matching name can be found. Otherwise NULL is returned. */
1003
1004const char *
1005ctf_enum_name (ctf_file_t *fp, ctf_id_t type, int value)
1006{
1007 ctf_file_t *ofp = fp;
1008 const ctf_type_t *tp;
1009 const ctf_enum_t *ep;
676c3ecb 1010 const ctf_dtdef_t *dtd;
316afdb1
NA
1011 ssize_t increment;
1012 uint32_t n;
1013
1014 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1015 return NULL; /* errno is set for us. */
1016
1017 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1018 return NULL; /* errno is set for us. */
1019
1020 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1021 {
1022 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1023 return NULL;
1024 }
1025
1026 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1027
676c3ecb
NA
1028 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1029 {
1030 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
316afdb1 1031
676c3ecb
NA
1032 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1033 {
1034 if (ep->cte_value == value)
1035 return (ctf_strptr (fp, ep->cte_name));
1036 }
1037 }
1038 else
316afdb1 1039 {
676c3ecb
NA
1040 ctf_dmdef_t *dmd;
1041
1042 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1043 dmd != NULL; dmd = ctf_list_next (dmd))
1044 {
1045 if (dmd->dmd_value == value)
1046 return dmd->dmd_name;
1047 }
316afdb1
NA
1048 }
1049
1050 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1051 return NULL;
1052}
1053
1054/* Convert the specified enum tag name to the corresponding value, if a
1055 matching name can be found. Otherwise CTF_ERR is returned. */
1056
1057int
1058ctf_enum_value (ctf_file_t * fp, ctf_id_t type, const char *name, int *valp)
1059{
1060 ctf_file_t *ofp = fp;
1061 const ctf_type_t *tp;
1062 const ctf_enum_t *ep;
676c3ecb 1063 const ctf_dtdef_t *dtd;
316afdb1
NA
1064 ssize_t increment;
1065 uint32_t n;
1066
1067 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
a0486bac 1068 return -1; /* errno is set for us. */
316afdb1
NA
1069
1070 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1071 return -1; /* errno is set for us. */
316afdb1
NA
1072
1073 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1074 {
1075 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
a0486bac 1076 return -1;
316afdb1
NA
1077 }
1078
1079 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1080
1081 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1082
676c3ecb 1083 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
316afdb1 1084 {
676c3ecb 1085 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
316afdb1 1086 {
676c3ecb
NA
1087 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1088 {
1089 if (valp != NULL)
1090 *valp = ep->cte_value;
1091 return 0;
1092 }
1093 }
1094 }
1095 else
1096 {
1097 ctf_dmdef_t *dmd;
1098
1099 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1100 dmd != NULL; dmd = ctf_list_next (dmd))
1101 {
1102 if (strcmp (dmd->dmd_name, name) == 0)
1103 {
1104 if (valp != NULL)
1105 *valp = dmd->dmd_value;
1106 return 0;
1107 }
316afdb1
NA
1108 }
1109 }
1110
1111 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
a0486bac 1112 return -1;
316afdb1
NA
1113}
1114
12a0b67d
NA
1115/* Given a type ID relating to a function type, return info on return types and
1116 arg counts for that function. */
1117
1118int
1119ctf_func_type_info (ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1120{
1121 const ctf_type_t *tp;
1122 uint32_t kind;
1123 const uint32_t *args;
676c3ecb 1124 const ctf_dtdef_t *dtd;
12a0b67d
NA
1125 ssize_t size, increment;
1126
1127 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1128 return -1; /* errno is set for us. */
1129
1130 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1131 return -1; /* errno is set for us. */
1132
1133 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1134 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1135
1136 if (kind != CTF_K_FUNCTION)
1137 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1138
1139 fip->ctc_return = tp->ctt_type;
12a0b67d 1140 fip->ctc_flags = 0;
676c3ecb 1141 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
12a0b67d 1142
676c3ecb
NA
1143 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1144 args = (uint32_t *) ((uintptr_t) tp + increment);
1145 else
1146 args = (uint32_t *) dtd->dtd_u.dtu_argv;
12a0b67d
NA
1147
1148 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1149 {
1150 fip->ctc_flags |= CTF_FUNC_VARARG;
1151 fip->ctc_argc--;
1152 }
1153
1154 return 0;
1155}
1156
1157/* Given a type ID relating to a function type,, return the arguments for the
1158 function. */
1159
1160int
1161ctf_func_type_args (ctf_file_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
1162{
1163 const ctf_type_t *tp;
1164 const uint32_t *args;
676c3ecb 1165 const ctf_dtdef_t *dtd;
12a0b67d
NA
1166 ssize_t size, increment;
1167 ctf_funcinfo_t f;
1168
1169 if (ctf_func_type_info (fp, type, &f) < 0)
1170 return -1; /* errno is set for us. */
1171
1172 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1173 return -1; /* errno is set for us. */
1174
1175 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1176 return -1; /* errno is set for us. */
1177
1178 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1179
676c3ecb
NA
1180 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1181 args = (uint32_t *) ((uintptr_t) tp + increment);
1182 else
1183 args = (uint32_t *) dtd->dtd_u.dtu_argv;
12a0b67d
NA
1184
1185 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1186 *argv++ = *args++;
1187
1188 return 0;
1189}
1190
316afdb1
NA
1191/* Recursively visit the members of any type. This function is used as the
1192 engine for ctf_type_visit, below. We resolve the input type, recursively
1193 invoke ourself for each type member if the type is a struct or union, and
1194 then invoke the callback function on the current type. If any callback
1195 returns non-zero, we abort and percolate the error code back up to the top. */
1196
1197static int
1198ctf_type_rvisit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func,
1199 void *arg, const char *name, unsigned long offset, int depth)
1200{
1201 ctf_id_t otype = type;
1202 const ctf_type_t *tp;
676c3ecb 1203 const ctf_dtdef_t *dtd;
316afdb1
NA
1204 ssize_t size, increment;
1205 uint32_t kind, n;
1206 int rc;
1207
1208 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 1209 return -1; /* errno is set for us. */
316afdb1
NA
1210
1211 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1212 return -1; /* errno is set for us. */
316afdb1
NA
1213
1214 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1215 return rc;
1216
1217 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1218
1219 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1220 return 0;
1221
1222 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1223
676c3ecb 1224 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
316afdb1 1225 {
676c3ecb 1226 if (size < CTF_LSTRUCT_THRESH)
316afdb1 1227 {
676c3ecb
NA
1228 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1229 increment);
1230
1231 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1232 {
1233 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1234 func, arg, ctf_strptr (fp,
1235 mp->ctm_name),
1236 offset + mp->ctm_offset,
1237 depth + 1)) != 0)
1238 return rc;
1239 }
316afdb1 1240 }
676c3ecb
NA
1241 else
1242 {
1243 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1244 increment);
316afdb1 1245
676c3ecb
NA
1246 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1247 {
1248 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1249 func, arg, ctf_strptr (fp,
1250 lmp->ctlm_name),
1251 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1252 depth + 1)) != 0)
1253 return rc;
1254 }
1255 }
316afdb1
NA
1256 }
1257 else
1258 {
676c3ecb 1259 ctf_dmdef_t *dmd;
316afdb1 1260
676c3ecb
NA
1261 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1262 dmd != NULL; dmd = ctf_list_next (dmd))
316afdb1 1263 {
676c3ecb
NA
1264 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1265 dmd->dmd_name, dmd->dmd_offset,
316afdb1
NA
1266 depth + 1)) != 0)
1267 return rc;
1268 }
1269 }
1270
1271 return 0;
1272}
1273
1274/* Recursively visit the members of any type. We pass the name, member
1275 type, and offset of each member to the specified callback function. */
1276int
1277ctf_type_visit (ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1278{
1279 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1280}
This page took 0.114244 seconds and 4 git commands to generate.