libtool.m4: update GNU/Hurd test from upstream. In upstream libtool, 47a889a4ca20...
[deliverable/binutils-gdb.git] / libctf / ctf-types.c
CommitLineData
316afdb1 1/* Type handling functions.
250d07de 2 Copyright (C) 2019-2021 Free Software Foundation, Inc.
316afdb1
NA
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>
688d28f6 21#include <assert.h>
316afdb1
NA
22#include <string.h>
23
24/* Determine whether a type is a parent or a child. */
25
26int
139633c3 27ctf_type_isparent (ctf_dict_t *fp, ctf_id_t id)
316afdb1
NA
28{
29 return (LCTF_TYPE_ISPARENT (fp, id));
30}
31
32int
139633c3 33ctf_type_ischild (ctf_dict_t * fp, ctf_id_t id)
316afdb1
NA
34{
35 return (LCTF_TYPE_ISCHILD (fp, id));
36}
37
38/* Iterate over the members of a STRUCT or UNION. We pass the name, member
39 type, and offset of each member to the specified callback function. */
40
41int
139633c3 42ctf_member_iter (ctf_dict_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
316afdb1 43{
6c3a3877
NA
44 ctf_next_t *i = NULL;
45 ssize_t offset;
46 const char *name;
47 ctf_id_t membtype;
316afdb1
NA
48 int rc;
49
6c3a3877 50 while ((offset = ctf_member_next (fp, type, &i, &name, &membtype, 0)) >= 0)
316afdb1 51 {
6c3a3877 52 if ((rc = func (name, membtype, offset, arg)) != 0)
316afdb1 53 {
6c3a3877
NA
54 ctf_next_destroy (i);
55 return rc;
316afdb1
NA
56 }
57 }
6c3a3877
NA
58 if (ctf_errno (fp) != ECTF_NEXT_END)
59 return -1; /* errno is set for us. */
316afdb1
NA
60
61 return 0;
62}
63
688d28f6
NA
64/* Iterate over the members of a STRUCT or UNION, returning each member's
65 offset and optionally name and member type in turn. On end-of-iteration,
6c3a3877 66 returns -1. If FLAGS is CTF_MN_RECURSE, recurse into unnamed members. */
688d28f6
NA
67
68ssize_t
139633c3 69ctf_member_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
6c3a3877 70 const char **name, ctf_id_t *membtype, int flags)
688d28f6 71{
139633c3 72 ctf_dict_t *ofp = fp;
688d28f6
NA
73 uint32_t kind;
74 ssize_t offset;
75 ctf_next_t *i = *it;
76
77 if (!i)
78 {
79 const ctf_type_t *tp;
80 ctf_dtdef_t *dtd;
6c3a3877 81 ssize_t increment;
688d28f6
NA
82
83 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
84 return -1; /* errno is set for us. */
85
86 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
87 return -1; /* errno is set for us. */
88
89 if ((i = ctf_next_create ()) == NULL)
90 return ctf_set_errno (ofp, ENOMEM);
91 i->cu.ctn_fp = ofp;
92
6c3a3877 93 (void) ctf_get_ctt_size (fp, tp, &i->ctn_size, &increment);
688d28f6
NA
94 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
95
96 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
97 {
98 ctf_next_destroy (i);
99 return (ctf_set_errno (ofp, ECTF_NOTSOU));
100 }
101
102 dtd = ctf_dynamic_type (fp, type);
103 i->ctn_iter_fun = (void (*) (void)) ctf_member_next;
104
105 /* We depend below on the RDWR state indicating whether the DTD-related
106 fields or the DMD-related fields have been initialized. */
107
108 assert ((dtd && (fp->ctf_flags & LCTF_RDWR))
109 || (!dtd && (!(fp->ctf_flags & LCTF_RDWR))));
110
111 if (dtd == NULL)
112 {
113 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
114
115 if (i->ctn_size < CTF_LSTRUCT_THRESH)
6c3a3877 116 i->u.ctn_mp = (const ctf_member_t *) ((uintptr_t) tp + increment);
688d28f6 117 else
6c3a3877 118 i->u.ctn_lmp = (const ctf_lmember_t *) ((uintptr_t) tp + increment);
688d28f6
NA
119 }
120 else
121 i->u.ctn_dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
122
123 *it = i;
124 }
125
126 if ((void (*) (void)) ctf_member_next != i->ctn_iter_fun)
127 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN));
128
129 if (ofp != i->cu.ctn_fp)
130 return (ctf_set_errno (ofp, ECTF_NEXT_WRONGFP));
131
132 /* Resolve to the native dict of this type. */
133 if ((fp = ctf_get_dict (ofp, type)) == NULL)
134 return (ctf_set_errno (ofp, ECTF_NOPARENT));
135
6c3a3877
NA
136 /* When we hit an unnamed struct/union member, we set ctn_type to indicate
137 that we are inside one, then return the unnamed member: on the next call,
138 we must skip over top-level member iteration in favour of iteration within
139 the sub-struct until it later turns out that that iteration has ended. */
688d28f6 140
6c3a3877
NA
141 retry:
142 if (!i->ctn_type)
143 {
144 if (!(fp->ctf_flags & LCTF_RDWR))
688d28f6 145 {
6c3a3877
NA
146 if (i->ctn_n == 0)
147 goto end_iter;
148
149 if (i->ctn_size < CTF_LSTRUCT_THRESH)
150 {
151 const char *membname = ctf_strptr (fp, i->u.ctn_mp->ctm_name);
152
153 if (name)
154 *name = membname;
155 if (membtype)
156 *membtype = i->u.ctn_mp->ctm_type;
157 offset = i->u.ctn_mp->ctm_offset;
158
159 if (membname[0] == 0
160 && (ctf_type_kind (fp, i->u.ctn_mp->ctm_type) == CTF_K_STRUCT
161 || ctf_type_kind (fp, i->u.ctn_mp->ctm_type) == CTF_K_UNION))
162 i->ctn_type = i->u.ctn_mp->ctm_type;
163
164 i->u.ctn_mp++;
165 }
166 else
167 {
168 const char *membname = ctf_strptr (fp, i->u.ctn_lmp->ctlm_name);
169
170 if (name)
171 *name = membname;
172 if (membtype)
173 *membtype = i->u.ctn_lmp->ctlm_type;
174 offset = (unsigned long) CTF_LMEM_OFFSET (i->u.ctn_lmp);
175
176 if (membname[0] == 0
177 && (ctf_type_kind (fp, i->u.ctn_lmp->ctlm_type) == CTF_K_STRUCT
178 || ctf_type_kind (fp, i->u.ctn_lmp->ctlm_type) == CTF_K_UNION))
179 i->ctn_type = i->u.ctn_lmp->ctlm_type;
180
181 i->u.ctn_lmp++;
182 }
183 i->ctn_n--;
688d28f6
NA
184 }
185 else
186 {
6c3a3877
NA
187 if (i->u.ctn_dmd == NULL)
188 goto end_iter;
189 /* The dmd contains a NULL for unnamed dynamic members. Don't inflict
190 this on our callers. */
688d28f6 191 if (name)
6c3a3877
NA
192 {
193 if (i->u.ctn_dmd->dmd_name)
194 *name = i->u.ctn_dmd->dmd_name;
195 else
196 *name = "";
197 }
688d28f6 198 if (membtype)
6c3a3877
NA
199 *membtype = i->u.ctn_dmd->dmd_type;
200 offset = i->u.ctn_dmd->dmd_offset;
201
202 if (i->u.ctn_dmd->dmd_name == NULL
203 && (ctf_type_kind (fp, i->u.ctn_dmd->dmd_type) == CTF_K_STRUCT
204 || ctf_type_kind (fp, i->u.ctn_dmd->dmd_type) == CTF_K_UNION))
205 i->ctn_type = i->u.ctn_dmd->dmd_type;
206
207 i->u.ctn_dmd = ctf_list_next (i->u.ctn_dmd);
688d28f6 208 }
6c3a3877
NA
209
210 /* The callers might want automatic recursive sub-struct traversal. */
211 if (!(flags & CTF_MN_RECURSE))
212 i->ctn_type = 0;
213
214 /* Sub-struct traversal starting? Take note of the offset of this member,
215 for later boosting of sub-struct members' offsets. */
216 if (i->ctn_type)
217 i->ctn_increment = offset;
688d28f6 218 }
6c3a3877 219 /* Traversing a sub-struct? Just return it, with the offset adjusted. */
688d28f6
NA
220 else
221 {
6c3a3877
NA
222 ssize_t ret = ctf_member_next (fp, i->ctn_type, &i->ctn_next, name,
223 membtype, flags);
224
225 if (ret >= 0)
226 return ret + i->ctn_increment;
227
228 if (ctf_errno (fp) != ECTF_NEXT_END)
229 {
230 ctf_next_destroy (i);
231 *it = NULL;
232 i->ctn_type = 0;
233 return ret; /* errno is set for us. */
234 }
235
236 if (!ctf_assert (fp, (i->ctn_next == NULL)))
237 return -1; /* errno is set for us. */
238
239 i->ctn_type = 0;
240 /* This sub-struct has ended: on to the next real member. */
241 goto retry;
688d28f6
NA
242 }
243
244 return offset;
245
246 end_iter:
247 ctf_next_destroy (i);
248 *it = NULL;
249 return ctf_set_errno (ofp, ECTF_NEXT_END);
250}
251
316afdb1
NA
252/* Iterate over the members of an ENUM. We pass the string name and associated
253 integer value of each enum element to the specified callback function. */
254
255int
139633c3 256ctf_enum_iter (ctf_dict_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
316afdb1 257{
139633c3 258 ctf_dict_t *ofp = fp;
316afdb1
NA
259 const ctf_type_t *tp;
260 const ctf_enum_t *ep;
676c3ecb 261 ctf_dtdef_t *dtd;
316afdb1
NA
262 ssize_t increment;
263 uint32_t n;
264 int rc;
265
266 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
a0486bac 267 return -1; /* errno is set for us. */
316afdb1
NA
268
269 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 270 return -1; /* errno is set for us. */
316afdb1
NA
271
272 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
273 return (ctf_set_errno (ofp, ECTF_NOTENUM));
274
275 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
276
676c3ecb
NA
277 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
278 {
279 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
316afdb1 280
676c3ecb
NA
281 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
282 {
283 const char *name = ctf_strptr (fp, ep->cte_name);
284 if ((rc = func (name, ep->cte_value, arg)) != 0)
285 return rc;
286 }
287 }
288 else
316afdb1 289 {
676c3ecb
NA
290 ctf_dmdef_t *dmd;
291
292 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
293 dmd != NULL; dmd = ctf_list_next (dmd))
294 {
295 if ((rc = func (dmd->dmd_name, dmd->dmd_value, arg)) != 0)
296 return rc;
297 }
316afdb1
NA
298 }
299
300 return 0;
301}
302
688d28f6
NA
303/* Iterate over the members of an enum TYPE, returning each enumerand's NAME or
304 NULL at end of iteration or error, and optionally passing back the
305 enumerand's integer VALue. */
306
307const char *
139633c3 308ctf_enum_next (ctf_dict_t *fp, ctf_id_t type, ctf_next_t **it,
688d28f6
NA
309 int *val)
310{
139633c3 311 ctf_dict_t *ofp = fp;
688d28f6
NA
312 uint32_t kind;
313 const char *name;
314 ctf_next_t *i = *it;
315
316 if (!i)
317 {
318 const ctf_type_t *tp;
319 ctf_dtdef_t *dtd;
320
321 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
322 return NULL; /* errno is set for us. */
323
324 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
325 return NULL; /* errno is set for us. */
326
327 if ((i = ctf_next_create ()) == NULL)
328 {
329 ctf_set_errno (ofp, ENOMEM);
330 return NULL;
331 }
332 i->cu.ctn_fp = ofp;
333
334 (void) ctf_get_ctt_size (fp, tp, NULL,
335 &i->ctn_increment);
336 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
337
338 if (kind != CTF_K_ENUM)
339 {
340 ctf_next_destroy (i);
341 ctf_set_errno (ofp, ECTF_NOTENUM);
342 return NULL;
343 }
344
345 dtd = ctf_dynamic_type (fp, type);
346 i->ctn_iter_fun = (void (*) (void)) ctf_enum_next;
347
348 /* We depend below on the RDWR state indicating whether the DTD-related
349 fields or the DMD-related fields have been initialized. */
350
351 assert ((dtd && (fp->ctf_flags & LCTF_RDWR))
352 || (!dtd && (!(fp->ctf_flags & LCTF_RDWR))));
353
354 if (dtd == NULL)
355 {
356 i->ctn_n = LCTF_INFO_VLEN (fp, tp->ctt_info);
357
358 i->u.ctn_en = (const ctf_enum_t *) ((uintptr_t) tp +
359 i->ctn_increment);
360 }
361 else
362 i->u.ctn_dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
363
364 *it = i;
365 }
366
367 if ((void (*) (void)) ctf_enum_next != i->ctn_iter_fun)
368 {
369 ctf_set_errno (ofp, ECTF_NEXT_WRONGFUN);
370 return NULL;
371 }
372
373 if (ofp != i->cu.ctn_fp)
374 {
375 ctf_set_errno (ofp, ECTF_NEXT_WRONGFP);
376 return NULL;
377 }
378
379 /* Resolve to the native dict of this type. */
380 if ((fp = ctf_get_dict (ofp, type)) == NULL)
381 {
382 ctf_set_errno (ofp, ECTF_NOPARENT);
383 return NULL;
384 }
385
386 if (!(fp->ctf_flags & LCTF_RDWR))
387 {
388 if (i->ctn_n == 0)
389 goto end_iter;
390
391 name = ctf_strptr (fp, i->u.ctn_en->cte_name);
392 if (val)
393 *val = i->u.ctn_en->cte_value;
394 i->u.ctn_en++;
395 i->ctn_n--;
396 }
397 else
398 {
399 if (i->u.ctn_dmd == NULL)
400 goto end_iter;
401
402 name = i->u.ctn_dmd->dmd_name;
403 if (val)
404 *val = i->u.ctn_dmd->dmd_value;
405 i->u.ctn_dmd = ctf_list_next (i->u.ctn_dmd);
406 }
407
408 return name;
409
410 end_iter:
411 ctf_next_destroy (i);
412 *it = NULL;
413 ctf_set_errno (ofp, ECTF_NEXT_END);
414 return NULL;
415}
416
139633c3 417/* Iterate over every root (user-visible) type in the given CTF dict.
688d28f6
NA
418 We pass the type ID of each type to the specified callback function.
419
420 Does not traverse parent types: you have to do that explicitly. This is by
421 design, to avoid traversing them more than once if traversing many children
422 of a single parent. */
316afdb1
NA
423
424int
139633c3 425ctf_type_iter (ctf_dict_t *fp, ctf_type_f *func, void *arg)
316afdb1
NA
426{
427 ctf_id_t id, max = fp->ctf_typemax;
428 int rc, child = (fp->ctf_flags & LCTF_CHILD);
429
430 for (id = 1; id <= max; id++)
431 {
432 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
433 if (LCTF_INFO_ISROOT (fp, tp->ctt_info)
434 && (rc = func (LCTF_INDEX_TO_TYPE (fp, id, child), arg)) != 0)
435 return rc;
436 }
437
438 return 0;
439}
440
139633c3 441/* Iterate over every type in the given CTF dict, user-visible or not.
688d28f6
NA
442 We pass the type ID of each type to the specified callback function.
443
444 Does not traverse parent types: you have to do that explicitly. This is by
445 design, to avoid traversing them more than once if traversing many children
446 of a single parent. */
0ac62312
NA
447
448int
139633c3 449ctf_type_iter_all (ctf_dict_t *fp, ctf_type_all_f *func, void *arg)
0ac62312
NA
450{
451 ctf_id_t id, max = fp->ctf_typemax;
452 int rc, child = (fp->ctf_flags & LCTF_CHILD);
453
454 for (id = 1; id <= max; id++)
455 {
456 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, id);
457 if ((rc = func (LCTF_INDEX_TO_TYPE (fp, id, child),
458 LCTF_INFO_ISROOT(fp, tp->ctt_info)
459 ? CTF_ADD_ROOT : CTF_ADD_NONROOT, arg) != 0))
460 return rc;
461 }
462
463 return 0;
464}
465
139633c3 466/* Iterate over every type in the given CTF dict, optionally including
688d28f6
NA
467 non-user-visible types, returning each type ID and hidden flag in turn.
468 Returns CTF_ERR on end of iteration or error.
469
470 Does not traverse parent types: you have to do that explicitly. This is by
471 design, to avoid traversing them more than once if traversing many children
472 of a single parent. */
473
474ctf_id_t
139633c3 475ctf_type_next (ctf_dict_t *fp, ctf_next_t **it, int *flag, int want_hidden)
688d28f6
NA
476{
477 ctf_next_t *i = *it;
478
479 if (!i)
480 {
481 if ((i = ctf_next_create ()) == NULL)
482 return ctf_set_errno (fp, ENOMEM);
483
484 i->cu.ctn_fp = fp;
485 i->ctn_type = 1;
486 i->ctn_iter_fun = (void (*) (void)) ctf_type_next;
487 *it = i;
488 }
489
490 if ((void (*) (void)) ctf_type_next != i->ctn_iter_fun)
491 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
492
493 if (fp != i->cu.ctn_fp)
494 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
495
496 while (i->ctn_type <= fp->ctf_typemax)
497 {
498 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR (fp, i->ctn_type);
499
500 if ((!want_hidden) && (!LCTF_INFO_ISROOT (fp, tp->ctt_info)))
501 {
502 i->ctn_type++;
503 continue;
504 }
505
506 if (flag)
507 *flag = LCTF_INFO_ISROOT (fp, tp->ctt_info);
508 return LCTF_INDEX_TO_TYPE (fp, i->ctn_type++, fp->ctf_flags & LCTF_CHILD);
509 }
510 ctf_next_destroy (i);
511 *it = NULL;
512 return ctf_set_errno (fp, ECTF_NEXT_END);
513}
514
139633c3 515/* Iterate over every variable in the given CTF dict, in arbitrary order.
316afdb1
NA
516 We pass the name of each variable to the specified callback function. */
517
518int
139633c3 519ctf_variable_iter (ctf_dict_t *fp, ctf_variable_f *func, void *arg)
316afdb1 520{
316afdb1
NA
521 int rc;
522
523 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
b7190c82 524 return (ctf_set_errno (fp, ECTF_NOPARENT));
316afdb1 525
676c3ecb
NA
526 if (!(fp->ctf_flags & LCTF_RDWR))
527 {
528 unsigned long i;
529 for (i = 0; i < fp->ctf_nvars; i++)
530 if ((rc = func (ctf_strptr (fp, fp->ctf_vars[i].ctv_name),
531 fp->ctf_vars[i].ctv_type, arg)) != 0)
532 return rc;
533 }
534 else
535 {
536 ctf_dvdef_t *dvd;
537
538 for (dvd = ctf_list_next (&fp->ctf_dvdefs); dvd != NULL;
539 dvd = ctf_list_next (dvd))
540 {
541 if ((rc = func (dvd->dvd_name, dvd->dvd_type, arg)) != 0)
542 return rc;
543 }
544 }
316afdb1
NA
545
546 return 0;
547}
548
139633c3 549/* Iterate over every variable in the given CTF dict, in arbitrary order,
688d28f6
NA
550 returning the name and type of each variable in turn. The name argument is
551 not optional. Returns CTF_ERR on end of iteration or error. */
552
553ctf_id_t
139633c3 554ctf_variable_next (ctf_dict_t *fp, ctf_next_t **it, const char **name)
688d28f6
NA
555{
556 ctf_next_t *i = *it;
557
558 if ((fp->ctf_flags & LCTF_CHILD) && (fp->ctf_parent == NULL))
559 return (ctf_set_errno (fp, ECTF_NOPARENT));
560
561 if (!i)
562 {
563 if ((i = ctf_next_create ()) == NULL)
564 return ctf_set_errno (fp, ENOMEM);
565
566 i->cu.ctn_fp = fp;
567 i->ctn_iter_fun = (void (*) (void)) ctf_variable_next;
568 if (fp->ctf_flags & LCTF_RDWR)
569 i->u.ctn_dvd = ctf_list_next (&fp->ctf_dvdefs);
570 *it = i;
571 }
572
573 if ((void (*) (void)) ctf_variable_next != i->ctn_iter_fun)
574 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFUN));
575
576 if (fp != i->cu.ctn_fp)
577 return (ctf_set_errno (fp, ECTF_NEXT_WRONGFP));
578
579 if (!(fp->ctf_flags & LCTF_RDWR))
580 {
581 if (i->ctn_n >= fp->ctf_nvars)
582 goto end_iter;
583
584 *name = ctf_strptr (fp, fp->ctf_vars[i->ctn_n].ctv_name);
585 return fp->ctf_vars[i->ctn_n++].ctv_type;
586 }
587 else
588 {
589 ctf_id_t id;
590
591 if (i->u.ctn_dvd == NULL)
592 goto end_iter;
593
594 *name = i->u.ctn_dvd->dvd_name;
595 id = i->u.ctn_dvd->dvd_type;
596 i->u.ctn_dvd = ctf_list_next (i->u.ctn_dvd);
597 return id;
598 }
599
600 end_iter:
601 ctf_next_destroy (i);
602 *it = NULL;
603 return ctf_set_errno (fp, ECTF_NEXT_END);
604}
605
316afdb1
NA
606/* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
607 RESTRICT nodes until we reach a "base" type node. This is useful when
608 we want to follow a type ID to a node that has members or a size. To guard
609 against infinite loops, we implement simplified cycle detection and check
610 each link against itself, the previous node, and the topmost node.
611
ffeece6a
NA
612 Does not drill down through slices to their contained type.
613
614 Callers of this function must not presume that a type it returns must have a
615 valid ctt_size: forwards do not, and must be separately handled. */
316afdb1
NA
616
617ctf_id_t
139633c3 618ctf_type_resolve (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
619{
620 ctf_id_t prev = type, otype = type;
139633c3 621 ctf_dict_t *ofp = fp;
316afdb1
NA
622 const ctf_type_t *tp;
623
791915db
NA
624 if (type == 0)
625 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
626
316afdb1
NA
627 while ((tp = ctf_lookup_by_id (&fp, type)) != NULL)
628 {
629 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
630 {
631 case CTF_K_TYPEDEF:
632 case CTF_K_VOLATILE:
633 case CTF_K_CONST:
634 case CTF_K_RESTRICT:
635 if (tp->ctt_type == type || tp->ctt_type == otype
636 || tp->ctt_type == prev)
637 {
926c9e76
NA
638 ctf_err_warn (ofp, 0, ECTF_CORRUPT, _("type %lx cycle detected"),
639 otype);
316afdb1
NA
640 return (ctf_set_errno (ofp, ECTF_CORRUPT));
641 }
642 prev = type;
643 type = tp->ctt_type;
644 break;
645 default:
646 return type;
647 }
791915db
NA
648 if (type == 0)
649 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
316afdb1
NA
650 }
651
652 return CTF_ERR; /* errno is set for us. */
653}
654
655/* Like ctf_type_resolve(), but traverse down through slices to their contained
656 type. */
657
658ctf_id_t
139633c3 659ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
660{
661 const ctf_type_t *tp;
662
663 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
664 return -1;
665
666 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
667 return CTF_ERR; /* errno is set for us. */
668
669 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
670 return ctf_type_reference (fp, type);
671 return type;
672}
673
1136c379
NA
674/* Return the native dict of a given type: if called on a child and the
675 type is in the parent, return the parent. Needed if you plan to access
676 the type directly, without using the API. */
677ctf_dict_t *
678ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
679{
680 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
681 return fp->ctf_parent;
682
683 return fp;
684}
685
676c3ecb
NA
686/* Look up a name in the given name table, in the appropriate hash given the
687 kind of the identifier. The name is a raw, undecorated identifier. */
688
139633c3 689ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
676c3ecb
NA
690{
691 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
692}
693
694/* Look up a name in the given name table, in the appropriate hash given the
695 readability state of the dictionary. The name is a raw, undecorated
696 identifier. */
697
139633c3 698ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
676c3ecb
NA
699{
700 ctf_id_t id;
701
702 if (fp->ctf_flags & LCTF_RDWR)
8c419a91 703 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
676c3ecb
NA
704 else
705 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
706 return id;
707}
708
96e3ec29 709/* Lookup the given type ID and return its name as a new dynamically-allocated
316afdb1
NA
710 string. */
711
712char *
139633c3 713ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
714{
715 ctf_decl_t cd;
716 ctf_decl_node_t *cdp;
717 ctf_decl_prec_t prec, lp, rp;
718 int ptr, arr;
719 uint32_t k;
720 char *buf;
721
722 if (fp == NULL && type == CTF_ERR)
723 return NULL; /* Simplify caller code by permitting CTF_ERR. */
724
725 ctf_decl_init (&cd);
726 ctf_decl_push (&cd, fp, type);
727
728 if (cd.cd_err != 0)
729 {
730 ctf_decl_fini (&cd);
731 ctf_set_errno (fp, cd.cd_err);
732 return NULL;
733 }
734
735 /* If the type graph's order conflicts with lexical precedence order
736 for pointers or arrays, then we need to surround the declarations at
737 the corresponding lexical precedence with parentheses. This can
738 result in either a parenthesized pointer (*) as in int (*)() or
739 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
740
741 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
742 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
743
744 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
745 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
746
747 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
748
749 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
750 {
751 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
752 cdp != NULL; cdp = ctf_list_next (cdp))
753 {
139633c3 754 ctf_dict_t *rfp = fp;
316afdb1
NA
755 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
756 const char *name = ctf_strptr (rfp, tp->ctt_name);
757
758 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
759 ctf_decl_sprintf (&cd, " ");
760
761 if (lp == prec)
762 {
763 ctf_decl_sprintf (&cd, "(");
764 lp = -1;
765 }
766
767 switch (cdp->cd_kind)
768 {
769 case CTF_K_INTEGER:
770 case CTF_K_FLOAT:
771 case CTF_K_TYPEDEF:
96e3ec29
NA
772 /* Integers, floats, and typedefs must always be named types. */
773
774 if (name[0] == '\0')
775 {
776 ctf_set_errno (fp, ECTF_CORRUPT);
777 ctf_decl_fini (&cd);
778 return NULL;
779 }
780
316afdb1
NA
781 ctf_decl_sprintf (&cd, "%s", name);
782 break;
783 case CTF_K_POINTER:
784 ctf_decl_sprintf (&cd, "*");
785 break;
786 case CTF_K_ARRAY:
787 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
788 break;
789 case CTF_K_FUNCTION:
c6e9a1e5
NA
790 {
791 size_t i;
792 ctf_funcinfo_t fi;
793 ctf_id_t *argv = NULL;
794
795 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
796 goto err; /* errno is set for us. */
797
798 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
799 {
800 ctf_set_errno (rfp, errno);
801 goto err;
802 }
803
804 if (ctf_func_type_args (rfp, cdp->cd_type,
805 fi.ctc_argc, argv) < 0)
806 goto err; /* errno is set for us. */
807
808 ctf_decl_sprintf (&cd, "(*) (");
809 for (i = 0; i < fi.ctc_argc; i++)
810 {
811 char *arg = ctf_type_aname (rfp, argv[i]);
812
813 if (arg == NULL)
814 goto err; /* errno is set for us. */
815 ctf_decl_sprintf (&cd, "%s", arg);
816 free (arg);
817
818 if ((i < fi.ctc_argc - 1)
819 || (fi.ctc_flags & CTF_FUNC_VARARG))
820 ctf_decl_sprintf (&cd, ", ");
821 }
822
823 if (fi.ctc_flags & CTF_FUNC_VARARG)
824 ctf_decl_sprintf (&cd, "...");
825 ctf_decl_sprintf (&cd, ")");
826
827 free (argv);
828 break;
829
830 err:
831 free (argv);
832 ctf_decl_fini (&cd);
833 return NULL;
834 }
316afdb1
NA
835 break;
836 case CTF_K_STRUCT:
316afdb1
NA
837 ctf_decl_sprintf (&cd, "struct %s", name);
838 break;
839 case CTF_K_UNION:
840 ctf_decl_sprintf (&cd, "union %s", name);
841 break;
842 case CTF_K_ENUM:
843 ctf_decl_sprintf (&cd, "enum %s", name);
844 break;
b4b6ea46
NA
845 case CTF_K_FORWARD:
846 {
847 switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
848 {
849 case CTF_K_STRUCT:
850 ctf_decl_sprintf (&cd, "struct %s", name);
851 break;
852 case CTF_K_UNION:
853 ctf_decl_sprintf (&cd, "union %s", name);
854 break;
855 case CTF_K_ENUM:
856 ctf_decl_sprintf (&cd, "enum %s", name);
857 break;
858 default:
859 ctf_set_errno (fp, ECTF_CORRUPT);
860 ctf_decl_fini (&cd);
861 return NULL;
862 }
863 break;
864 }
316afdb1
NA
865 case CTF_K_VOLATILE:
866 ctf_decl_sprintf (&cd, "volatile");
867 break;
868 case CTF_K_CONST:
869 ctf_decl_sprintf (&cd, "const");
870 break;
871 case CTF_K_RESTRICT:
872 ctf_decl_sprintf (&cd, "restrict");
873 break;
316afdb1
NA
874 }
875
876 k = cdp->cd_kind;
877 }
878
879 if (rp == prec)
880 ctf_decl_sprintf (&cd, ")");
881 }
882
883 if (cd.cd_enomem)
884 (void) ctf_set_errno (fp, ENOMEM);
885
886 buf = ctf_decl_buf (&cd);
887
888 ctf_decl_fini (&cd);
889 return buf;
890}
891
892/* Lookup the given type ID and print a string name for it into buf. Return
893 the actual number of bytes (not including \0) needed to format the name. */
894
895ssize_t
139633c3 896ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
316afdb1
NA
897{
898 char *str = ctf_type_aname (fp, type);
1a6ab13e 899 size_t slen;
316afdb1
NA
900
901 if (str == NULL)
fa56cdcd 902 return CTF_ERR; /* errno is set for us. */
316afdb1 903
1a6ab13e 904 slen = strlen (str);
316afdb1
NA
905 snprintf (buf, len, "%s", str);
906 free (str);
907
908 if (slen >= len)
909 (void) ctf_set_errno (fp, ECTF_NAMELEN);
910
911 return slen;
912}
913
914/* Lookup the given type ID and print a string name for it into buf. If buf
915 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
916
917char *
139633c3 918ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
316afdb1
NA
919{
920 ssize_t rv = ctf_type_lname (fp, type, buf, len);
921 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
922}
923
01d93174 924/* Lookup the given type ID and return its raw, unadorned, undecorated name.
139633c3 925 The name will live as long as its ctf_dict_t does. */
12a0b67d 926
01d93174 927const char *
139633c3 928ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
12a0b67d
NA
929{
930 const ctf_type_t *tp;
931
932 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
933 return NULL; /* errno is set for us. */
934
01d93174
NA
935 return ctf_strraw (fp, tp->ctt_name);
936}
937
938/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
939 new dynamically-allocated string. */
940
941char *
139633c3 942ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
01d93174
NA
943{
944 const char *name = ctf_type_name_raw (fp, type);
945
946 if (name != NULL)
947 return strdup (name);
12a0b67d
NA
948
949 return NULL;
950}
951
316afdb1
NA
952/* Resolve the type down to a base type node, and then return the size
953 of the type storage in bytes. */
954
955ssize_t
139633c3 956ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
316afdb1 957{
ffeece6a 958 ctf_dict_t *ofp = fp;
316afdb1
NA
959 const ctf_type_t *tp;
960 ssize_t size;
961 ctf_arinfo_t ar;
962
963 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
964 return -1; /* errno is set for us. */
965
966 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
967 return -1; /* errno is set for us. */
968
969 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
970 {
971 case CTF_K_POINTER:
972 return fp->ctf_dmodel->ctd_pointer;
973
974 case CTF_K_FUNCTION:
975 return 0; /* Function size is only known by symtab. */
976
977 case CTF_K_ENUM:
978 return fp->ctf_dmodel->ctd_int;
979
980 case CTF_K_ARRAY:
981 /* ctf_add_array() does not directly encode the element size, but
982 requires the user to multiply to determine the element size.
983
984 If ctf_get_ctt_size() returns nonzero, then use the recorded
985 size instead. */
986
987 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
988 return size;
989
ffeece6a
NA
990 if (ctf_array_info (ofp, type, &ar) < 0
991 || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
316afdb1
NA
992 return -1; /* errno is set for us. */
993
994 return size * ar.ctr_nelems;
995
ffeece6a
NA
996 case CTF_K_FORWARD:
997 /* Forwards do not have a meaningful size. */
998 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
999
316afdb1
NA
1000 default: /* including slices of enums, etc */
1001 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1002 }
1003}
1004
1005/* Resolve the type down to a base type node, and then return the alignment
1006 needed for the type storage in bytes.
1007
1008 XXX may need arch-dependent attention. */
1009
1010ssize_t
139633c3 1011ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
1012{
1013 const ctf_type_t *tp;
139633c3 1014 ctf_dict_t *ofp = fp;
316afdb1
NA
1015 int kind;
1016
1017 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1018 return -1; /* errno is set for us. */
1019
1020 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1021 return -1; /* errno is set for us. */
1022
1023 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1024 switch (kind)
1025 {
1026 case CTF_K_POINTER:
1027 case CTF_K_FUNCTION:
1028 return fp->ctf_dmodel->ctd_pointer;
1029
1030 case CTF_K_ARRAY:
1031 {
1032 ctf_arinfo_t r;
ffeece6a 1033 if (ctf_array_info (ofp, type, &r) < 0)
316afdb1 1034 return -1; /* errno is set for us. */
ffeece6a 1035 return (ctf_type_align (ofp, r.ctr_contents));
316afdb1
NA
1036 }
1037
1038 case CTF_K_STRUCT:
1039 case CTF_K_UNION:
1040 {
1041 size_t align = 0;
1042 ctf_dtdef_t *dtd;
1043
1044 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1045 {
1046 uint32_t n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1047 ssize_t size, increment;
1048 const void *vmp;
1049
1050 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1051 vmp = (unsigned char *) tp + increment;
1052
1053 if (kind == CTF_K_STRUCT)
1054 n = MIN (n, 1); /* Only use first member for structs. */
1055
1056 if (size < CTF_LSTRUCT_THRESH)
1057 {
1058 const ctf_member_t *mp = vmp;
1059 for (; n != 0; n--, mp++)
1060 {
ffeece6a 1061 ssize_t am = ctf_type_align (ofp, mp->ctm_type);
a0486bac 1062 align = MAX (align, (size_t) am);
316afdb1
NA
1063 }
1064 }
1065 else
1066 {
1067 const ctf_lmember_t *lmp = vmp;
1068 for (; n != 0; n--, lmp++)
1069 {
ffeece6a 1070 ssize_t am = ctf_type_align (ofp, lmp->ctlm_type);
a0486bac 1071 align = MAX (align, (size_t) am);
316afdb1
NA
1072 }
1073 }
1074 }
1075 else
1076 {
1077 ctf_dmdef_t *dmd;
1078
1079 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1080 dmd != NULL; dmd = ctf_list_next (dmd))
1081 {
ffeece6a 1082 ssize_t am = ctf_type_align (ofp, dmd->dmd_type);
a0486bac 1083 align = MAX (align, (size_t) am);
316afdb1
NA
1084 if (kind == CTF_K_STRUCT)
1085 break;
1086 }
1087 }
1088
1089 return align;
1090 }
1091
1092 case CTF_K_ENUM:
1093 return fp->ctf_dmodel->ctd_int;
1094
ffeece6a
NA
1095 case CTF_K_FORWARD:
1096 /* Forwards do not have a meaningful alignment. */
1097 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1098
316afdb1
NA
1099 default: /* including slices of enums, etc */
1100 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1101 }
1102}
1103
1104/* Return the kind (CTF_K_* constant) for the specified type ID. */
1105
1106int
139633c3 1107ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
1108{
1109 const ctf_type_t *tp;
1110
1111 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1112 return -1; /* errno is set for us. */
316afdb1
NA
1113
1114 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1115}
1116
1117/* Return the kind (CTF_K_* constant) for the specified type ID.
1118 Slices are considered to be of the same kind as the type sliced. */
1119
1120int
139633c3 1121ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
1122{
1123 int kind;
1124
a0486bac
JM
1125 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1126 return -1;
316afdb1
NA
1127
1128 if (kind == CTF_K_SLICE)
1129 {
1130 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
a0486bac 1131 return -1;
316afdb1
NA
1132 kind = ctf_type_kind_unsliced (fp, type);
1133 }
1134
1135 return kind;
1136}
1137
9b15cbb7
NA
1138/* Return the kind of this type, except, for forwards, return the kind of thing
1139 this is a forward to. */
1140int
139633c3 1141ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
9b15cbb7
NA
1142{
1143 int kind;
1144 const ctf_type_t *tp;
1145
1146 if ((kind = ctf_type_kind (fp, type)) < 0)
1147 return -1; /* errno is set for us. */
1148
1149 if (kind != CTF_K_FORWARD)
1150 return kind;
1151
1152 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1153 return -1; /* errno is set for us. */
1154
1155 return tp->ctt_type;
1156}
1157
316afdb1
NA
1158/* If the type is one that directly references another type (such as POINTER),
1159 then return the ID of the type to which it refers. */
1160
1161ctf_id_t
139633c3 1162ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
316afdb1 1163{
139633c3 1164 ctf_dict_t *ofp = fp;
316afdb1
NA
1165 const ctf_type_t *tp;
1166
1167 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1168 return CTF_ERR; /* errno is set for us. */
1169
1170 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1171 {
1172 case CTF_K_POINTER:
1173 case CTF_K_TYPEDEF:
1174 case CTF_K_VOLATILE:
1175 case CTF_K_CONST:
1176 case CTF_K_RESTRICT:
1177 return tp->ctt_type;
1178 /* Slices store their type in an unusual place. */
1179 case CTF_K_SLICE:
1180 {
43706199 1181 ctf_dtdef_t *dtd;
316afdb1 1182 const ctf_slice_t *sp;
43706199
NA
1183
1184 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1185 {
1186 ssize_t increment;
1187
1188 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1189 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1190 }
1191 else
1192 sp = &dtd->dtd_u.dtu_slice;
1193
316afdb1
NA
1194 return sp->cts_type;
1195 }
1196 default:
1197 return (ctf_set_errno (ofp, ECTF_NOTREF));
1198 }
1199}
1200
1201/* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1202 pointer to the given type, see if we can compute a pointer to the type
1203 resulting from resolving the type down to its base type and use that
1204 instead. This helps with cases where the CTF data includes "struct foo *"
1205 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1206
139633c3 1207 XXX what about parent dicts? */
316afdb1
NA
1208
1209ctf_id_t
139633c3 1210ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
316afdb1 1211{
139633c3 1212 ctf_dict_t *ofp = fp;
316afdb1
NA
1213 ctf_id_t ntype;
1214
1215 if (ctf_lookup_by_id (&fp, type) == NULL)
1216 return CTF_ERR; /* errno is set for us. */
1217
1218 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1219 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1220
1221 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1222 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1223
1224 if (ctf_lookup_by_id (&fp, type) == NULL)
1225 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1226
1227 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1228 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1229
1230 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1231}
1232
1233/* Return the encoding for the specified INTEGER or FLOAT. */
1234
1235int
139633c3 1236ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
316afdb1 1237{
139633c3 1238 ctf_dict_t *ofp = fp;
316afdb1
NA
1239 ctf_dtdef_t *dtd;
1240 const ctf_type_t *tp;
1241 ssize_t increment;
1242 uint32_t data;
1243
1244 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1245 return -1; /* errno is set for us. */
316afdb1
NA
1246
1247 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1248 {
9c1a2295
NA
1249 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1250 {
1251 case CTF_K_INTEGER:
1252 case CTF_K_FLOAT:
1253 *ep = dtd->dtd_u.dtu_enc;
1254 break;
1255 case CTF_K_SLICE:
1256 {
1257 const ctf_slice_t *slice;
1258 ctf_encoding_t underlying_en;
502e838e
NA
1259 ctf_id_t underlying;
1260
9c1a2295 1261 slice = &dtd->dtd_u.dtu_slice;
502e838e
NA
1262 underlying = ctf_type_resolve (fp, slice->cts_type);
1263 data = ctf_type_encoding (fp, underlying, &underlying_en);
9c1a2295 1264
9c1a2295
NA
1265 ep->cte_format = underlying_en.cte_format;
1266 ep->cte_offset = slice->cts_offset;
1267 ep->cte_bits = slice->cts_bits;
1268 break;
1269 }
1270 default:
1271 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1272 }
316afdb1
NA
1273 return 0;
1274 }
1275
1276 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1277
1278 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1279 {
1280 case CTF_K_INTEGER:
1281 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1282 ep->cte_format = CTF_INT_ENCODING (data);
1283 ep->cte_offset = CTF_INT_OFFSET (data);
1284 ep->cte_bits = CTF_INT_BITS (data);
1285 break;
1286 case CTF_K_FLOAT:
1287 data = *(const uint32_t *) ((uintptr_t) tp + increment);
1288 ep->cte_format = CTF_FP_ENCODING (data);
1289 ep->cte_offset = CTF_FP_OFFSET (data);
1290 ep->cte_bits = CTF_FP_BITS (data);
1291 break;
1292 case CTF_K_SLICE:
1293 {
1294 const ctf_slice_t *slice;
1295 ctf_encoding_t underlying_en;
502e838e 1296 ctf_id_t underlying;
316afdb1
NA
1297
1298 slice = (ctf_slice_t *) ((uintptr_t) tp + increment);
502e838e
NA
1299 underlying = ctf_type_resolve (fp, slice->cts_type);
1300 data = ctf_type_encoding (fp, underlying, &underlying_en);
316afdb1
NA
1301
1302 ep->cte_format = underlying_en.cte_format;
1303 ep->cte_offset = slice->cts_offset;
1304 ep->cte_bits = slice->cts_bits;
1305 break;
1306 }
1307 default:
1308 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1309 }
1310
1311 return 0;
1312}
1313
1314int
139633c3 1315ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
316afdb1
NA
1316 ctf_id_t rtype)
1317{
1318 int rval;
1319
1320 if (ltype < rtype)
1321 rval = -1;
1322 else if (ltype > rtype)
1323 rval = 1;
1324 else
1325 rval = 0;
1326
1327 if (lfp == rfp)
1328 return rval;
1329
1330 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1331 lfp = lfp->ctf_parent;
1332
1333 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1334 rfp = rfp->ctf_parent;
1335
1336 if (lfp < rfp)
1337 return -1;
1338
1339 if (lfp > rfp)
1340 return 1;
1341
1342 return rval;
1343}
1344
1345/* Return a boolean value indicating if two types are compatible. This function
1346 returns true if the two types are the same, or if they (or their ultimate
1347 base type) have the same encoding properties, or (for structs / unions /
1348 enums / forward declarations) if they have the same name and (for structs /
1349 unions) member count. */
1350
1351int
139633c3
NA
1352ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1353 ctf_dict_t *rfp, ctf_id_t rtype)
316afdb1
NA
1354{
1355 const ctf_type_t *ltp, *rtp;
1356 ctf_encoding_t le, re;
1357 ctf_arinfo_t la, ra;
1358 uint32_t lkind, rkind;
1359 int same_names = 0;
1360
1361 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1362 return 1;
1363
1364 ltype = ctf_type_resolve (lfp, ltype);
1365 lkind = ctf_type_kind (lfp, ltype);
1366
1367 rtype = ctf_type_resolve (rfp, rtype);
1368 rkind = ctf_type_kind (rfp, rtype);
1369
1370 ltp = ctf_lookup_by_id (&lfp, ltype);
1371 rtp = ctf_lookup_by_id (&rfp, rtype);
1372
1373 if (ltp != NULL && rtp != NULL)
1374 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1375 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1376
1377 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1378 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1379 return 1;
1380
1381 if (lkind != rkind)
1382 return 0;
1383
1384 switch (lkind)
1385 {
1386 case CTF_K_INTEGER:
1387 case CTF_K_FLOAT:
1388 memset (&le, 0, sizeof (le));
1389 memset (&re, 0, sizeof (re));
1390 return (ctf_type_encoding (lfp, ltype, &le) == 0
1391 && ctf_type_encoding (rfp, rtype, &re) == 0
1392 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1393 case CTF_K_POINTER:
1394 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1395 rfp, ctf_type_reference (rfp, rtype)));
1396 case CTF_K_ARRAY:
1397 return (ctf_array_info (lfp, ltype, &la) == 0
1398 && ctf_array_info (rfp, rtype, &ra) == 0
1399 && la.ctr_nelems == ra.ctr_nelems
1400 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1401 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1402 case CTF_K_STRUCT:
1403 case CTF_K_UNION:
1404 return (same_names && (ctf_type_size (lfp, ltype)
1405 == ctf_type_size (rfp, rtype)));
1406 case CTF_K_ENUM:
1407 {
1408 int lencoded, rencoded;
1409 lencoded = ctf_type_encoding (lfp, ltype, &le);
1410 rencoded = ctf_type_encoding (rfp, rtype, &re);
1411
1412 if ((lencoded != rencoded) ||
1413 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1414 return 0;
1415 }
1416 /* FALLTHRU */
1417 case CTF_K_FORWARD:
1418 return same_names; /* No other checks required for these type kinds. */
1419 default:
1420 return 0; /* Should not get here since we did a resolve. */
1421 }
1422}
1423
e0325e2c 1424/* Return the number of members in a STRUCT or UNION, or the number of
6c3a3877 1425 enumerators in an ENUM. The count does not include unnamed sub-members. */
e0325e2c
NA
1426
1427int
139633c3 1428ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
e0325e2c 1429{
139633c3 1430 ctf_dict_t *ofp = fp;
e0325e2c
NA
1431 const ctf_type_t *tp;
1432 uint32_t kind;
1433
1434 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1435 return -1; /* errno is set for us. */
1436
1437 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1438 return -1; /* errno is set for us. */
1439
1440 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1441
1442 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1443 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1444
1445 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1446}
1447
316afdb1
NA
1448/* Return the type and offset for a given member of a STRUCT or UNION. */
1449
1450int
139633c3 1451ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
316afdb1
NA
1452 ctf_membinfo_t *mip)
1453{
139633c3 1454 ctf_dict_t *ofp = fp;
316afdb1 1455 const ctf_type_t *tp;
676c3ecb 1456 ctf_dtdef_t *dtd;
316afdb1
NA
1457 ssize_t size, increment;
1458 uint32_t kind, n;
1459
1460 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 1461 return -1; /* errno is set for us. */
316afdb1
NA
1462
1463 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1464 return -1; /* errno is set for us. */
316afdb1
NA
1465
1466 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1467 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1468
1469 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1470 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1471
676c3ecb 1472 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
316afdb1 1473 {
676c3ecb
NA
1474 if (size < CTF_LSTRUCT_THRESH)
1475 {
1476 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1477 increment);
316afdb1 1478
676c3ecb
NA
1479 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1480 {
6c3a3877
NA
1481 const char *membname = ctf_strptr (fp, mp->ctm_name);
1482
1483 if (membname[0] == 0
1484 && (ctf_type_kind (fp, mp->ctm_type) == CTF_K_STRUCT
1485 || ctf_type_kind (fp, mp->ctm_type) == CTF_K_UNION)
1486 && (ctf_member_info (fp, mp->ctm_type, name, mip) == 0))
1487 return 0;
1488
1489 if (strcmp (membname, name) == 0)
676c3ecb
NA
1490 {
1491 mip->ctm_type = mp->ctm_type;
1492 mip->ctm_offset = mp->ctm_offset;
1493 return 0;
1494 }
1495 }
1496 }
1497 else
316afdb1 1498 {
676c3ecb
NA
1499 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1500 increment);
1501
1502 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
316afdb1 1503 {
6c3a3877
NA
1504 const char *membname = ctf_strptr (fp, lmp->ctlm_name);
1505
1506 if (membname[0] == 0
1507 && (ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_STRUCT
1508 || ctf_type_kind (fp, lmp->ctlm_type) == CTF_K_UNION)
1509 && (ctf_member_info (fp, lmp->ctlm_type, name, mip) == 0))
1510 return 0;
1511
1512 if (strcmp (membname, name) == 0)
676c3ecb
NA
1513 {
1514 mip->ctm_type = lmp->ctlm_type;
1515 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (lmp);
1516 return 0;
1517 }
316afdb1
NA
1518 }
1519 }
1520 }
1521 else
1522 {
676c3ecb 1523 ctf_dmdef_t *dmd;
316afdb1 1524
676c3ecb
NA
1525 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1526 dmd != NULL; dmd = ctf_list_next (dmd))
316afdb1 1527 {
6c3a3877
NA
1528 if (dmd->dmd_name == NULL
1529 && (ctf_type_kind (fp, dmd->dmd_type) == CTF_K_STRUCT
1530 || ctf_type_kind (fp, dmd->dmd_type) == CTF_K_UNION)
1531 && (ctf_member_info (fp, dmd->dmd_type, name, mip) == 0))
1532 return 0;
1533
1534 if (dmd->dmd_name != NULL
1535 && strcmp (dmd->dmd_name, name) == 0)
316afdb1 1536 {
676c3ecb
NA
1537 mip->ctm_type = dmd->dmd_type;
1538 mip->ctm_offset = dmd->dmd_offset;
316afdb1
NA
1539 return 0;
1540 }
1541 }
1542 }
1543
1544 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1545}
1546
1547/* Return the array type, index, and size information for the specified ARRAY. */
1548
1549int
139633c3 1550ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
316afdb1 1551{
139633c3 1552 ctf_dict_t *ofp = fp;
316afdb1
NA
1553 const ctf_type_t *tp;
1554 const ctf_array_t *ap;
1555 const ctf_dtdef_t *dtd;
1556 ssize_t increment;
1557
1558 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1559 return -1; /* errno is set for us. */
316afdb1
NA
1560
1561 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1562 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1563
1564 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
1565 {
1566 *arp = dtd->dtd_u.dtu_arr;
1567 return 0;
1568 }
1569
1570 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1571
1572 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
1573 arp->ctr_contents = ap->cta_contents;
1574 arp->ctr_index = ap->cta_index;
1575 arp->ctr_nelems = ap->cta_nelems;
1576
1577 return 0;
1578}
1579
1580/* Convert the specified value to the corresponding enum tag name, if a
1581 matching name can be found. Otherwise NULL is returned. */
1582
1583const char *
139633c3 1584ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
316afdb1 1585{
139633c3 1586 ctf_dict_t *ofp = fp;
316afdb1
NA
1587 const ctf_type_t *tp;
1588 const ctf_enum_t *ep;
676c3ecb 1589 const ctf_dtdef_t *dtd;
316afdb1
NA
1590 ssize_t increment;
1591 uint32_t n;
1592
1593 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1594 return NULL; /* errno is set for us. */
1595
1596 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1597 return NULL; /* errno is set for us. */
1598
1599 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1600 {
1601 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
1602 return NULL;
1603 }
1604
1605 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1606
676c3ecb
NA
1607 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1608 {
1609 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
316afdb1 1610
676c3ecb
NA
1611 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1612 {
1613 if (ep->cte_value == value)
1614 return (ctf_strptr (fp, ep->cte_name));
1615 }
1616 }
1617 else
316afdb1 1618 {
676c3ecb
NA
1619 ctf_dmdef_t *dmd;
1620
1621 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1622 dmd != NULL; dmd = ctf_list_next (dmd))
1623 {
1624 if (dmd->dmd_value == value)
1625 return dmd->dmd_name;
1626 }
316afdb1
NA
1627 }
1628
1629 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
1630 return NULL;
1631}
1632
1633/* Convert the specified enum tag name to the corresponding value, if a
1634 matching name can be found. Otherwise CTF_ERR is returned. */
1635
1636int
139633c3 1637ctf_enum_value (ctf_dict_t * fp, ctf_id_t type, const char *name, int *valp)
316afdb1 1638{
139633c3 1639 ctf_dict_t *ofp = fp;
316afdb1
NA
1640 const ctf_type_t *tp;
1641 const ctf_enum_t *ep;
676c3ecb 1642 const ctf_dtdef_t *dtd;
316afdb1
NA
1643 ssize_t increment;
1644 uint32_t n;
1645
1646 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
a0486bac 1647 return -1; /* errno is set for us. */
316afdb1
NA
1648
1649 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1650 return -1; /* errno is set for us. */
316afdb1
NA
1651
1652 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1653 {
1654 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
a0486bac 1655 return -1;
316afdb1
NA
1656 }
1657
1658 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1659
1660 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
1661
676c3ecb 1662 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
316afdb1 1663 {
676c3ecb 1664 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
316afdb1 1665 {
676c3ecb
NA
1666 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
1667 {
1668 if (valp != NULL)
1669 *valp = ep->cte_value;
1670 return 0;
1671 }
1672 }
1673 }
1674 else
1675 {
1676 ctf_dmdef_t *dmd;
1677
1678 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1679 dmd != NULL; dmd = ctf_list_next (dmd))
1680 {
1681 if (strcmp (dmd->dmd_name, name) == 0)
1682 {
1683 if (valp != NULL)
1684 *valp = dmd->dmd_value;
1685 return 0;
1686 }
316afdb1
NA
1687 }
1688 }
1689
1690 (void) ctf_set_errno (ofp, ECTF_NOENUMNAM);
a0486bac 1691 return -1;
316afdb1
NA
1692}
1693
12a0b67d
NA
1694/* Given a type ID relating to a function type, return info on return types and
1695 arg counts for that function. */
1696
1697int
139633c3 1698ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
12a0b67d
NA
1699{
1700 const ctf_type_t *tp;
1701 uint32_t kind;
1702 const uint32_t *args;
676c3ecb 1703 const ctf_dtdef_t *dtd;
12a0b67d
NA
1704 ssize_t size, increment;
1705
1706 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1707 return -1; /* errno is set for us. */
1708
1709 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1710 return -1; /* errno is set for us. */
1711
1712 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1713 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1714
1715 if (kind != CTF_K_FUNCTION)
1716 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1717
1718 fip->ctc_return = tp->ctt_type;
12a0b67d 1719 fip->ctc_flags = 0;
676c3ecb 1720 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
12a0b67d 1721
676c3ecb
NA
1722 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1723 args = (uint32_t *) ((uintptr_t) tp + increment);
1724 else
afd78bd6 1725 args = dtd->dtd_u.dtu_argv;
12a0b67d
NA
1726
1727 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1728 {
1729 fip->ctc_flags |= CTF_FUNC_VARARG;
1730 fip->ctc_argc--;
1731 }
1732
1733 return 0;
1734}
1735
afd78bd6 1736/* Given a type ID relating to a function type, return the arguments for the
12a0b67d
NA
1737 function. */
1738
1739int
139633c3 1740ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
12a0b67d
NA
1741{
1742 const ctf_type_t *tp;
1743 const uint32_t *args;
676c3ecb 1744 const ctf_dtdef_t *dtd;
12a0b67d
NA
1745 ssize_t size, increment;
1746 ctf_funcinfo_t f;
1747
1748 if (ctf_func_type_info (fp, type, &f) < 0)
1749 return -1; /* errno is set for us. */
1750
1751 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1752 return -1; /* errno is set for us. */
1753
1754 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1755 return -1; /* errno is set for us. */
1756
1757 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1758
676c3ecb
NA
1759 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1760 args = (uint32_t *) ((uintptr_t) tp + increment);
1761 else
afd78bd6 1762 args = dtd->dtd_u.dtu_argv;
12a0b67d
NA
1763
1764 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1765 *argv++ = *args++;
1766
1767 return 0;
1768}
1769
316afdb1
NA
1770/* Recursively visit the members of any type. This function is used as the
1771 engine for ctf_type_visit, below. We resolve the input type, recursively
1772 invoke ourself for each type member if the type is a struct or union, and
1773 then invoke the callback function on the current type. If any callback
1774 returns non-zero, we abort and percolate the error code back up to the top. */
1775
1776static int
139633c3 1777ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
316afdb1
NA
1778 void *arg, const char *name, unsigned long offset, int depth)
1779{
1780 ctf_id_t otype = type;
1781 const ctf_type_t *tp;
676c3ecb 1782 const ctf_dtdef_t *dtd;
316afdb1
NA
1783 ssize_t size, increment;
1784 uint32_t kind, n;
1785 int rc;
1786
1787 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 1788 return -1; /* errno is set for us. */
316afdb1
NA
1789
1790 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1791 return -1; /* errno is set for us. */
316afdb1
NA
1792
1793 if ((rc = func (name, otype, offset, depth, arg)) != 0)
1794 return rc;
1795
1796 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1797
1798 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1799 return 0;
1800
1801 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1802
676c3ecb 1803 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
316afdb1 1804 {
676c3ecb 1805 if (size < CTF_LSTRUCT_THRESH)
316afdb1 1806 {
676c3ecb
NA
1807 const ctf_member_t *mp = (const ctf_member_t *) ((uintptr_t) tp +
1808 increment);
1809
1810 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, mp++)
1811 {
1812 if ((rc = ctf_type_rvisit (fp, mp->ctm_type,
1813 func, arg, ctf_strptr (fp,
1814 mp->ctm_name),
1815 offset + mp->ctm_offset,
1816 depth + 1)) != 0)
1817 return rc;
1818 }
316afdb1 1819 }
676c3ecb
NA
1820 else
1821 {
1822 const ctf_lmember_t *lmp = (const ctf_lmember_t *) ((uintptr_t) tp +
1823 increment);
316afdb1 1824
676c3ecb
NA
1825 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, lmp++)
1826 {
1827 if ((rc = ctf_type_rvisit (fp, lmp->ctlm_type,
1828 func, arg, ctf_strptr (fp,
1829 lmp->ctlm_name),
1830 offset + (unsigned long) CTF_LMEM_OFFSET (lmp),
1831 depth + 1)) != 0)
1832 return rc;
1833 }
1834 }
316afdb1
NA
1835 }
1836 else
1837 {
676c3ecb 1838 ctf_dmdef_t *dmd;
316afdb1 1839
676c3ecb
NA
1840 for (dmd = ctf_list_next (&dtd->dtd_u.dtu_members);
1841 dmd != NULL; dmd = ctf_list_next (dmd))
316afdb1 1842 {
676c3ecb
NA
1843 if ((rc = ctf_type_rvisit (fp, dmd->dmd_type, func, arg,
1844 dmd->dmd_name, dmd->dmd_offset,
316afdb1
NA
1845 depth + 1)) != 0)
1846 return rc;
1847 }
1848 }
1849
1850 return 0;
1851}
1852
1853/* Recursively visit the members of any type. We pass the name, member
1854 type, and offset of each member to the specified callback function. */
1855int
139633c3 1856ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
316afdb1
NA
1857{
1858 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1859}
This page took 0.197546 seconds and 4 git commands to generate.