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