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