Automatic date update in version.in
[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;
49da556c
NA
582 case CTF_K_UNKNOWN:
583 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
316afdb1
NA
584 default:
585 return type;
586 }
791915db
NA
587 if (type == 0)
588 return (ctf_set_errno (ofp, ECTF_NONREPRESENTABLE));
316afdb1
NA
589 }
590
591 return CTF_ERR; /* errno is set for us. */
592}
593
594/* Like ctf_type_resolve(), but traverse down through slices to their contained
595 type. */
596
597ctf_id_t
139633c3 598ctf_type_resolve_unsliced (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
599{
600 const ctf_type_t *tp;
601
602 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
603 return -1;
604
605 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
606 return CTF_ERR; /* errno is set for us. */
607
608 if ((LCTF_INFO_KIND (fp, tp->ctt_info)) == CTF_K_SLICE)
609 return ctf_type_reference (fp, type);
610 return type;
611}
612
1136c379
NA
613/* Return the native dict of a given type: if called on a child and the
614 type is in the parent, return the parent. Needed if you plan to access
615 the type directly, without using the API. */
616ctf_dict_t *
617ctf_get_dict (ctf_dict_t *fp, ctf_id_t type)
618{
619 if ((fp->ctf_flags & LCTF_CHILD) && LCTF_TYPE_ISPARENT (fp, type))
620 return fp->ctf_parent;
621
622 return fp;
623}
624
676c3ecb
NA
625/* Look up a name in the given name table, in the appropriate hash given the
626 kind of the identifier. The name is a raw, undecorated identifier. */
627
139633c3 628ctf_id_t ctf_lookup_by_rawname (ctf_dict_t *fp, int kind, const char *name)
676c3ecb
NA
629{
630 return ctf_lookup_by_rawhash (fp, ctf_name_table (fp, kind), name);
631}
632
633/* Look up a name in the given name table, in the appropriate hash given the
634 readability state of the dictionary. The name is a raw, undecorated
635 identifier. */
636
139633c3 637ctf_id_t ctf_lookup_by_rawhash (ctf_dict_t *fp, ctf_names_t *np, const char *name)
676c3ecb
NA
638{
639 ctf_id_t id;
640
641 if (fp->ctf_flags & LCTF_RDWR)
8c419a91 642 id = (ctf_id_t) (uintptr_t) ctf_dynhash_lookup (np->ctn_writable, name);
676c3ecb
NA
643 else
644 id = ctf_hash_lookup_type (np->ctn_readonly, fp, name);
645 return id;
646}
647
96e3ec29 648/* Lookup the given type ID and return its name as a new dynamically-allocated
316afdb1
NA
649 string. */
650
651char *
139633c3 652ctf_type_aname (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
653{
654 ctf_decl_t cd;
655 ctf_decl_node_t *cdp;
656 ctf_decl_prec_t prec, lp, rp;
657 int ptr, arr;
658 uint32_t k;
659 char *buf;
660
661 if (fp == NULL && type == CTF_ERR)
662 return NULL; /* Simplify caller code by permitting CTF_ERR. */
663
664 ctf_decl_init (&cd);
665 ctf_decl_push (&cd, fp, type);
666
667 if (cd.cd_err != 0)
668 {
669 ctf_decl_fini (&cd);
670 ctf_set_errno (fp, cd.cd_err);
671 return NULL;
672 }
673
674 /* If the type graph's order conflicts with lexical precedence order
675 for pointers or arrays, then we need to surround the declarations at
676 the corresponding lexical precedence with parentheses. This can
677 result in either a parenthesized pointer (*) as in int (*)() or
678 int (*)[], or in a parenthesized pointer and array as in int (*[])(). */
679
680 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
681 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
682
683 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
684 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
685
686 k = CTF_K_POINTER; /* Avoid leading whitespace (see below). */
687
688 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++)
689 {
690 for (cdp = ctf_list_next (&cd.cd_nodes[prec]);
691 cdp != NULL; cdp = ctf_list_next (cdp))
692 {
139633c3 693 ctf_dict_t *rfp = fp;
316afdb1
NA
694 const ctf_type_t *tp = ctf_lookup_by_id (&rfp, cdp->cd_type);
695 const char *name = ctf_strptr (rfp, tp->ctt_name);
696
697 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
698 ctf_decl_sprintf (&cd, " ");
699
700 if (lp == prec)
701 {
702 ctf_decl_sprintf (&cd, "(");
703 lp = -1;
704 }
705
706 switch (cdp->cd_kind)
707 {
708 case CTF_K_INTEGER:
709 case CTF_K_FLOAT:
710 case CTF_K_TYPEDEF:
96e3ec29
NA
711 /* Integers, floats, and typedefs must always be named types. */
712
713 if (name[0] == '\0')
714 {
715 ctf_set_errno (fp, ECTF_CORRUPT);
716 ctf_decl_fini (&cd);
717 return NULL;
718 }
719
316afdb1
NA
720 ctf_decl_sprintf (&cd, "%s", name);
721 break;
722 case CTF_K_POINTER:
723 ctf_decl_sprintf (&cd, "*");
724 break;
725 case CTF_K_ARRAY:
726 ctf_decl_sprintf (&cd, "[%u]", cdp->cd_n);
727 break;
728 case CTF_K_FUNCTION:
c6e9a1e5
NA
729 {
730 size_t i;
731 ctf_funcinfo_t fi;
732 ctf_id_t *argv = NULL;
733
734 if (ctf_func_type_info (rfp, cdp->cd_type, &fi) < 0)
735 goto err; /* errno is set for us. */
736
737 if ((argv = calloc (fi.ctc_argc, sizeof (ctf_id_t *))) == NULL)
738 {
739 ctf_set_errno (rfp, errno);
740 goto err;
741 }
742
743 if (ctf_func_type_args (rfp, cdp->cd_type,
744 fi.ctc_argc, argv) < 0)
745 goto err; /* errno is set for us. */
746
747 ctf_decl_sprintf (&cd, "(*) (");
748 for (i = 0; i < fi.ctc_argc; i++)
749 {
750 char *arg = ctf_type_aname (rfp, argv[i]);
751
752 if (arg == NULL)
753 goto err; /* errno is set for us. */
754 ctf_decl_sprintf (&cd, "%s", arg);
755 free (arg);
756
757 if ((i < fi.ctc_argc - 1)
758 || (fi.ctc_flags & CTF_FUNC_VARARG))
759 ctf_decl_sprintf (&cd, ", ");
760 }
761
762 if (fi.ctc_flags & CTF_FUNC_VARARG)
763 ctf_decl_sprintf (&cd, "...");
764 ctf_decl_sprintf (&cd, ")");
765
766 free (argv);
767 break;
768
769 err:
770 free (argv);
771 ctf_decl_fini (&cd);
772 return NULL;
773 }
316afdb1
NA
774 break;
775 case CTF_K_STRUCT:
316afdb1
NA
776 ctf_decl_sprintf (&cd, "struct %s", name);
777 break;
778 case CTF_K_UNION:
779 ctf_decl_sprintf (&cd, "union %s", name);
780 break;
781 case CTF_K_ENUM:
782 ctf_decl_sprintf (&cd, "enum %s", name);
783 break;
b4b6ea46
NA
784 case CTF_K_FORWARD:
785 {
786 switch (ctf_type_kind_forwarded (fp, cdp->cd_type))
787 {
788 case CTF_K_STRUCT:
789 ctf_decl_sprintf (&cd, "struct %s", name);
790 break;
791 case CTF_K_UNION:
792 ctf_decl_sprintf (&cd, "union %s", name);
793 break;
794 case CTF_K_ENUM:
795 ctf_decl_sprintf (&cd, "enum %s", name);
796 break;
797 default:
798 ctf_set_errno (fp, ECTF_CORRUPT);
799 ctf_decl_fini (&cd);
800 return NULL;
801 }
802 break;
803 }
316afdb1
NA
804 case CTF_K_VOLATILE:
805 ctf_decl_sprintf (&cd, "volatile");
806 break;
807 case CTF_K_CONST:
808 ctf_decl_sprintf (&cd, "const");
809 break;
810 case CTF_K_RESTRICT:
811 ctf_decl_sprintf (&cd, "restrict");
812 break;
49da556c
NA
813 case CTF_K_UNKNOWN:
814 if (name[0] == '\0')
815 ctf_decl_sprintf (&cd, _("(nonrepresentable type)"));
816 else
817 ctf_decl_sprintf (&cd, _("(nonrepresentable type %s)"),
818 name);
819 break;
316afdb1
NA
820 }
821
822 k = cdp->cd_kind;
823 }
824
825 if (rp == prec)
826 ctf_decl_sprintf (&cd, ")");
827 }
828
829 if (cd.cd_enomem)
830 (void) ctf_set_errno (fp, ENOMEM);
831
832 buf = ctf_decl_buf (&cd);
833
834 ctf_decl_fini (&cd);
835 return buf;
836}
837
838/* Lookup the given type ID and print a string name for it into buf. Return
839 the actual number of bytes (not including \0) needed to format the name. */
840
841ssize_t
139633c3 842ctf_type_lname (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
316afdb1
NA
843{
844 char *str = ctf_type_aname (fp, type);
1a6ab13e 845 size_t slen;
316afdb1
NA
846
847 if (str == NULL)
fa56cdcd 848 return CTF_ERR; /* errno is set for us. */
316afdb1 849
1a6ab13e 850 slen = strlen (str);
316afdb1
NA
851 snprintf (buf, len, "%s", str);
852 free (str);
853
854 if (slen >= len)
855 (void) ctf_set_errno (fp, ECTF_NAMELEN);
856
857 return slen;
858}
859
860/* Lookup the given type ID and print a string name for it into buf. If buf
861 is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us. */
862
863char *
139633c3 864ctf_type_name (ctf_dict_t *fp, ctf_id_t type, char *buf, size_t len)
316afdb1
NA
865{
866 ssize_t rv = ctf_type_lname (fp, type, buf, len);
867 return (rv >= 0 && (size_t) rv < len ? buf : NULL);
868}
869
01d93174 870/* Lookup the given type ID and return its raw, unadorned, undecorated name.
ee87f50b
NA
871 The name will live as long as its ctf_dict_t does.
872
873 The only decoration is that a NULL return always means an error: nameless
874 types return a null string. */
12a0b67d 875
01d93174 876const char *
139633c3 877ctf_type_name_raw (ctf_dict_t *fp, ctf_id_t type)
12a0b67d
NA
878{
879 const ctf_type_t *tp;
880
881 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
882 return NULL; /* errno is set for us. */
883
ee87f50b
NA
884 if (tp->ctt_name == 0)
885 return "";
886
01d93174
NA
887 return ctf_strraw (fp, tp->ctt_name);
888}
889
890/* Lookup the given type ID and return its raw, unadorned, undecorated name as a
891 new dynamically-allocated string. */
892
893char *
139633c3 894ctf_type_aname_raw (ctf_dict_t *fp, ctf_id_t type)
01d93174
NA
895{
896 const char *name = ctf_type_name_raw (fp, type);
897
898 if (name != NULL)
899 return strdup (name);
12a0b67d
NA
900
901 return NULL;
902}
903
316afdb1
NA
904/* Resolve the type down to a base type node, and then return the size
905 of the type storage in bytes. */
906
907ssize_t
139633c3 908ctf_type_size (ctf_dict_t *fp, ctf_id_t type)
316afdb1 909{
ffeece6a 910 ctf_dict_t *ofp = fp;
316afdb1
NA
911 const ctf_type_t *tp;
912 ssize_t size;
913 ctf_arinfo_t ar;
914
915 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
916 return -1; /* errno is set for us. */
917
918 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
919 return -1; /* errno is set for us. */
920
921 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
922 {
923 case CTF_K_POINTER:
924 return fp->ctf_dmodel->ctd_pointer;
925
926 case CTF_K_FUNCTION:
927 return 0; /* Function size is only known by symtab. */
928
929 case CTF_K_ENUM:
930 return fp->ctf_dmodel->ctd_int;
931
932 case CTF_K_ARRAY:
933 /* ctf_add_array() does not directly encode the element size, but
934 requires the user to multiply to determine the element size.
935
936 If ctf_get_ctt_size() returns nonzero, then use the recorded
937 size instead. */
938
939 if ((size = ctf_get_ctt_size (fp, tp, NULL, NULL)) > 0)
940 return size;
941
ffeece6a
NA
942 if (ctf_array_info (ofp, type, &ar) < 0
943 || (size = ctf_type_size (ofp, ar.ctr_contents)) < 0)
316afdb1
NA
944 return -1; /* errno is set for us. */
945
946 return size * ar.ctr_nelems;
947
ffeece6a
NA
948 case CTF_K_FORWARD:
949 /* Forwards do not have a meaningful size. */
950 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
951
316afdb1
NA
952 default: /* including slices of enums, etc */
953 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
954 }
955}
956
957/* Resolve the type down to a base type node, and then return the alignment
958 needed for the type storage in bytes.
959
960 XXX may need arch-dependent attention. */
961
962ssize_t
139633c3 963ctf_type_align (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
964{
965 const ctf_type_t *tp;
139633c3 966 ctf_dict_t *ofp = fp;
316afdb1
NA
967 int kind;
968
969 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
970 return -1; /* errno is set for us. */
971
972 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
973 return -1; /* errno is set for us. */
974
975 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
976 switch (kind)
977 {
978 case CTF_K_POINTER:
979 case CTF_K_FUNCTION:
980 return fp->ctf_dmodel->ctd_pointer;
981
982 case CTF_K_ARRAY:
983 {
984 ctf_arinfo_t r;
ffeece6a 985 if (ctf_array_info (ofp, type, &r) < 0)
316afdb1 986 return -1; /* errno is set for us. */
ffeece6a 987 return (ctf_type_align (ofp, r.ctr_contents));
316afdb1
NA
988 }
989
990 case CTF_K_STRUCT:
991 case CTF_K_UNION:
992 {
993 size_t align = 0;
994 ctf_dtdef_t *dtd;
d7b1416e
NA
995 unsigned char *vlen;
996 uint32_t i = 0, n = LCTF_INFO_VLEN (fp, tp->ctt_info);
997 ssize_t size, increment, vbytes;
316afdb1 998
d7b1416e 999 ctf_get_ctt_size (fp, tp, &size, &increment);
316afdb1 1000
d7b1416e
NA
1001 if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1002 {
1003 vlen = dtd->dtd_vlen;
1004 vbytes = dtd->dtd_vlen_alloc;
1005 }
08c428af 1006 else
d7b1416e
NA
1007 {
1008 vlen = (unsigned char *) tp + increment;
1009 vbytes = LCTF_VBYTES (fp, kind, size, n);
1010 }
08c428af
NA
1011
1012 if (kind == CTF_K_STRUCT)
1013 n = MIN (n, 1); /* Only use first member for structs. */
1014
d7b1416e 1015 for (; n != 0; n--, i++)
08c428af 1016 {
d7b1416e
NA
1017 ctf_lmember_t memb;
1018
1019 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1020 return -1; /* errno is set for us. */
1021
1022 ssize_t am = ctf_type_align (ofp, memb.ctlm_type);
1023 align = MAX (align, (size_t) am);
316afdb1 1024 }
316afdb1
NA
1025 return align;
1026 }
1027
1028 case CTF_K_ENUM:
1029 return fp->ctf_dmodel->ctd_int;
1030
ffeece6a
NA
1031 case CTF_K_FORWARD:
1032 /* Forwards do not have a meaningful alignment. */
1033 return (ctf_set_errno (ofp, ECTF_INCOMPLETE));
1034
316afdb1
NA
1035 default: /* including slices of enums, etc */
1036 return (ctf_get_ctt_size (fp, tp, NULL, NULL));
1037 }
1038}
1039
1040/* Return the kind (CTF_K_* constant) for the specified type ID. */
1041
1042int
139633c3 1043ctf_type_kind_unsliced (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
1044{
1045 const ctf_type_t *tp;
1046
1047 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1048 return -1; /* errno is set for us. */
316afdb1
NA
1049
1050 return (LCTF_INFO_KIND (fp, tp->ctt_info));
1051}
1052
1053/* Return the kind (CTF_K_* constant) for the specified type ID.
1054 Slices are considered to be of the same kind as the type sliced. */
1055
1056int
139633c3 1057ctf_type_kind (ctf_dict_t *fp, ctf_id_t type)
316afdb1
NA
1058{
1059 int kind;
1060
a0486bac
JM
1061 if ((kind = ctf_type_kind_unsliced (fp, type)) < 0)
1062 return -1;
316afdb1
NA
1063
1064 if (kind == CTF_K_SLICE)
1065 {
1066 if ((type = ctf_type_reference (fp, type)) == CTF_ERR)
a0486bac 1067 return -1;
316afdb1
NA
1068 kind = ctf_type_kind_unsliced (fp, type);
1069 }
1070
1071 return kind;
1072}
1073
9b15cbb7
NA
1074/* Return the kind of this type, except, for forwards, return the kind of thing
1075 this is a forward to. */
1076int
139633c3 1077ctf_type_kind_forwarded (ctf_dict_t *fp, ctf_id_t type)
9b15cbb7
NA
1078{
1079 int kind;
1080 const ctf_type_t *tp;
1081
1082 if ((kind = ctf_type_kind (fp, type)) < 0)
1083 return -1; /* errno is set for us. */
1084
1085 if (kind != CTF_K_FORWARD)
1086 return kind;
1087
1088 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1089 return -1; /* errno is set for us. */
1090
1091 return tp->ctt_type;
1092}
1093
316afdb1
NA
1094/* If the type is one that directly references another type (such as POINTER),
1095 then return the ID of the type to which it refers. */
1096
1097ctf_id_t
139633c3 1098ctf_type_reference (ctf_dict_t *fp, ctf_id_t type)
316afdb1 1099{
139633c3 1100 ctf_dict_t *ofp = fp;
316afdb1
NA
1101 const ctf_type_t *tp;
1102
1103 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1104 return CTF_ERR; /* errno is set for us. */
1105
1106 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1107 {
1108 case CTF_K_POINTER:
1109 case CTF_K_TYPEDEF:
1110 case CTF_K_VOLATILE:
1111 case CTF_K_CONST:
1112 case CTF_K_RESTRICT:
1113 return tp->ctt_type;
1114 /* Slices store their type in an unusual place. */
1115 case CTF_K_SLICE:
1116 {
43706199 1117 ctf_dtdef_t *dtd;
316afdb1 1118 const ctf_slice_t *sp;
43706199
NA
1119
1120 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
1121 {
1122 ssize_t increment;
1123
1124 (void) ctf_get_ctt_size (fp, tp, NULL, &increment);
1125 sp = (const ctf_slice_t *) ((uintptr_t) tp + increment);
1126 }
1127 else
7879dd88 1128 sp = (const ctf_slice_t *) dtd->dtd_vlen;
43706199 1129
316afdb1
NA
1130 return sp->cts_type;
1131 }
1132 default:
1133 return (ctf_set_errno (ofp, ECTF_NOTREF));
1134 }
1135}
1136
1137/* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
1138 pointer to the given type, see if we can compute a pointer to the type
1139 resulting from resolving the type down to its base type and use that
1140 instead. This helps with cases where the CTF data includes "struct foo *"
1141 but not "foo_t *" and the user accesses "foo_t *" in the debugger.
1142
139633c3 1143 XXX what about parent dicts? */
316afdb1
NA
1144
1145ctf_id_t
139633c3 1146ctf_type_pointer (ctf_dict_t *fp, ctf_id_t type)
316afdb1 1147{
139633c3 1148 ctf_dict_t *ofp = fp;
316afdb1
NA
1149 ctf_id_t ntype;
1150
1151 if (ctf_lookup_by_id (&fp, type) == NULL)
1152 return CTF_ERR; /* errno is set for us. */
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 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1158 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1159
1160 if (ctf_lookup_by_id (&fp, type) == NULL)
1161 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1162
1163 if ((ntype = fp->ctf_ptrtab[LCTF_TYPE_TO_INDEX (fp, type)]) != 0)
1164 return (LCTF_INDEX_TO_TYPE (fp, ntype, (fp->ctf_flags & LCTF_CHILD)));
1165
1166 return (ctf_set_errno (ofp, ECTF_NOTYPE));
1167}
1168
69a28486 1169/* Return the encoding for the specified INTEGER, FLOAT, or ENUM. */
316afdb1
NA
1170
1171int
139633c3 1172ctf_type_encoding (ctf_dict_t *fp, ctf_id_t type, ctf_encoding_t *ep)
316afdb1 1173{
139633c3 1174 ctf_dict_t *ofp = fp;
316afdb1
NA
1175 ctf_dtdef_t *dtd;
1176 const ctf_type_t *tp;
1177 ssize_t increment;
7879dd88 1178 const unsigned char *vlen;
316afdb1
NA
1179 uint32_t data;
1180
1181 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1182 return -1; /* errno is set for us. */
316afdb1
NA
1183
1184 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
7879dd88
NA
1185 vlen = dtd->dtd_vlen;
1186 else
316afdb1 1187 {
7879dd88
NA
1188 ctf_get_ctt_size (fp, tp, NULL, &increment);
1189 vlen = (const unsigned char *) ((uintptr_t) tp + increment);
316afdb1
NA
1190 }
1191
316afdb1
NA
1192 switch (LCTF_INFO_KIND (fp, tp->ctt_info))
1193 {
1194 case CTF_K_INTEGER:
7879dd88 1195 data = *(const uint32_t *) vlen;
316afdb1
NA
1196 ep->cte_format = CTF_INT_ENCODING (data);
1197 ep->cte_offset = CTF_INT_OFFSET (data);
1198 ep->cte_bits = CTF_INT_BITS (data);
1199 break;
1200 case CTF_K_FLOAT:
7879dd88 1201 data = *(const uint32_t *) vlen;
316afdb1
NA
1202 ep->cte_format = CTF_FP_ENCODING (data);
1203 ep->cte_offset = CTF_FP_OFFSET (data);
1204 ep->cte_bits = CTF_FP_BITS (data);
1205 break;
69a28486
NA
1206 case CTF_K_ENUM:
1207 /* v3 only: we must guess at the underlying integral format. */
1208 ep->cte_format = CTF_INT_SIGNED;
1209 ep->cte_offset = 0;
1210 ep->cte_bits = 0;
1211 break;
316afdb1
NA
1212 case CTF_K_SLICE:
1213 {
1214 const ctf_slice_t *slice;
1215 ctf_encoding_t underlying_en;
502e838e 1216 ctf_id_t underlying;
316afdb1 1217
7879dd88 1218 slice = (ctf_slice_t *) vlen;
502e838e 1219 underlying = ctf_type_resolve (fp, slice->cts_type);
7879dd88
NA
1220 if (ctf_type_encoding (fp, underlying, &underlying_en) < 0)
1221 return -1; /* errno is set for us. */
316afdb1
NA
1222
1223 ep->cte_format = underlying_en.cte_format;
1224 ep->cte_offset = slice->cts_offset;
1225 ep->cte_bits = slice->cts_bits;
1226 break;
1227 }
1228 default:
1229 return (ctf_set_errno (ofp, ECTF_NOTINTFP));
1230 }
1231
1232 return 0;
1233}
1234
1235int
139633c3 1236ctf_type_cmp (ctf_dict_t *lfp, ctf_id_t ltype, ctf_dict_t *rfp,
316afdb1
NA
1237 ctf_id_t rtype)
1238{
1239 int rval;
1240
1241 if (ltype < rtype)
1242 rval = -1;
1243 else if (ltype > rtype)
1244 rval = 1;
1245 else
1246 rval = 0;
1247
1248 if (lfp == rfp)
1249 return rval;
1250
1251 if (LCTF_TYPE_ISPARENT (lfp, ltype) && lfp->ctf_parent != NULL)
1252 lfp = lfp->ctf_parent;
1253
1254 if (LCTF_TYPE_ISPARENT (rfp, rtype) && rfp->ctf_parent != NULL)
1255 rfp = rfp->ctf_parent;
1256
1257 if (lfp < rfp)
1258 return -1;
1259
1260 if (lfp > rfp)
1261 return 1;
1262
1263 return rval;
1264}
1265
1266/* Return a boolean value indicating if two types are compatible. This function
1267 returns true if the two types are the same, or if they (or their ultimate
1268 base type) have the same encoding properties, or (for structs / unions /
1269 enums / forward declarations) if they have the same name and (for structs /
1270 unions) member count. */
1271
1272int
139633c3
NA
1273ctf_type_compat (ctf_dict_t *lfp, ctf_id_t ltype,
1274 ctf_dict_t *rfp, ctf_id_t rtype)
316afdb1
NA
1275{
1276 const ctf_type_t *ltp, *rtp;
1277 ctf_encoding_t le, re;
1278 ctf_arinfo_t la, ra;
1279 uint32_t lkind, rkind;
1280 int same_names = 0;
1281
1282 if (ctf_type_cmp (lfp, ltype, rfp, rtype) == 0)
1283 return 1;
1284
1285 ltype = ctf_type_resolve (lfp, ltype);
1286 lkind = ctf_type_kind (lfp, ltype);
1287
1288 rtype = ctf_type_resolve (rfp, rtype);
1289 rkind = ctf_type_kind (rfp, rtype);
1290
1291 ltp = ctf_lookup_by_id (&lfp, ltype);
1292 rtp = ctf_lookup_by_id (&rfp, rtype);
1293
1294 if (ltp != NULL && rtp != NULL)
1295 same_names = (strcmp (ctf_strptr (lfp, ltp->ctt_name),
1296 ctf_strptr (rfp, rtp->ctt_name)) == 0);
1297
1298 if (((lkind == CTF_K_ENUM) && (rkind == CTF_K_INTEGER)) ||
1299 ((rkind == CTF_K_ENUM) && (lkind == CTF_K_INTEGER)))
1300 return 1;
1301
1302 if (lkind != rkind)
1303 return 0;
1304
1305 switch (lkind)
1306 {
1307 case CTF_K_INTEGER:
1308 case CTF_K_FLOAT:
1309 memset (&le, 0, sizeof (le));
1310 memset (&re, 0, sizeof (re));
1311 return (ctf_type_encoding (lfp, ltype, &le) == 0
1312 && ctf_type_encoding (rfp, rtype, &re) == 0
1313 && memcmp (&le, &re, sizeof (ctf_encoding_t)) == 0);
1314 case CTF_K_POINTER:
1315 return (ctf_type_compat (lfp, ctf_type_reference (lfp, ltype),
1316 rfp, ctf_type_reference (rfp, rtype)));
1317 case CTF_K_ARRAY:
1318 return (ctf_array_info (lfp, ltype, &la) == 0
1319 && ctf_array_info (rfp, rtype, &ra) == 0
1320 && la.ctr_nelems == ra.ctr_nelems
1321 && ctf_type_compat (lfp, la.ctr_contents, rfp, ra.ctr_contents)
1322 && ctf_type_compat (lfp, la.ctr_index, rfp, ra.ctr_index));
1323 case CTF_K_STRUCT:
1324 case CTF_K_UNION:
1325 return (same_names && (ctf_type_size (lfp, ltype)
1326 == ctf_type_size (rfp, rtype)));
1327 case CTF_K_ENUM:
1328 {
1329 int lencoded, rencoded;
1330 lencoded = ctf_type_encoding (lfp, ltype, &le);
1331 rencoded = ctf_type_encoding (rfp, rtype, &re);
1332
1333 if ((lencoded != rencoded) ||
1334 ((lencoded == 0) && memcmp (&le, &re, sizeof (ctf_encoding_t)) != 0))
1335 return 0;
1336 }
1337 /* FALLTHRU */
1338 case CTF_K_FORWARD:
1339 return same_names; /* No other checks required for these type kinds. */
1340 default:
1341 return 0; /* Should not get here since we did a resolve. */
1342 }
1343}
1344
e0325e2c 1345/* Return the number of members in a STRUCT or UNION, or the number of
6c3a3877 1346 enumerators in an ENUM. The count does not include unnamed sub-members. */
e0325e2c
NA
1347
1348int
139633c3 1349ctf_member_count (ctf_dict_t *fp, ctf_id_t type)
e0325e2c 1350{
139633c3 1351 ctf_dict_t *ofp = fp;
e0325e2c
NA
1352 const ctf_type_t *tp;
1353 uint32_t kind;
1354
1355 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1356 return -1; /* errno is set for us. */
1357
1358 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1359 return -1; /* errno is set for us. */
1360
1361 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1362
1363 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION && kind != CTF_K_ENUM)
1364 return (ctf_set_errno (ofp, ECTF_NOTSUE));
1365
1366 return LCTF_INFO_VLEN (fp, tp->ctt_info);
1367}
1368
316afdb1
NA
1369/* Return the type and offset for a given member of a STRUCT or UNION. */
1370
1371int
139633c3 1372ctf_member_info (ctf_dict_t *fp, ctf_id_t type, const char *name,
316afdb1
NA
1373 ctf_membinfo_t *mip)
1374{
139633c3 1375 ctf_dict_t *ofp = fp;
316afdb1 1376 const ctf_type_t *tp;
676c3ecb 1377 ctf_dtdef_t *dtd;
d7b1416e
NA
1378 unsigned char *vlen;
1379 ssize_t size, increment, vbytes;
1380 uint32_t kind, n, i = 0;
316afdb1
NA
1381
1382 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
a0486bac 1383 return -1; /* errno is set for us. */
316afdb1
NA
1384
1385 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1386 return -1; /* errno is set for us. */
316afdb1 1387
d7b1416e 1388 ctf_get_ctt_size (fp, tp, &size, &increment);
316afdb1
NA
1389 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1390
1391 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1392 return (ctf_set_errno (ofp, ECTF_NOTSOU));
1393
d7b1416e
NA
1394 n = LCTF_INFO_VLEN (fp, tp->ctt_info);
1395 if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
1396 {
1397 vlen = dtd->dtd_vlen;
1398 vbytes = dtd->dtd_vlen_alloc;
1399 }
08c428af 1400 else
d7b1416e
NA
1401 {
1402 vlen = (unsigned char *) tp + increment;
1403 vbytes = LCTF_VBYTES (fp, kind, size, n);
1404 }
6c3a3877 1405
d7b1416e 1406 for (; n != 0; n--, i++)
08c428af 1407 {
d7b1416e
NA
1408 ctf_lmember_t memb;
1409 const char *membname;
6c3a3877 1410
d7b1416e
NA
1411 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1412 return -1; /* errno is set for us. */
676c3ecb 1413
d7b1416e 1414 membname = ctf_strptr (fp, memb.ctlm_name);
6c3a3877 1415
d7b1416e
NA
1416 if (membname[0] == 0
1417 && (ctf_type_kind (fp, memb.ctlm_type) == CTF_K_STRUCT
1418 || ctf_type_kind (fp, memb.ctlm_type) == CTF_K_UNION)
1419 && (ctf_member_info (fp, memb.ctlm_type, name, mip) == 0))
1420 return 0;
316afdb1 1421
d7b1416e 1422 if (strcmp (membname, name) == 0)
316afdb1 1423 {
d7b1416e
NA
1424 mip->ctm_type = memb.ctlm_type;
1425 mip->ctm_offset = (unsigned long) CTF_LMEM_OFFSET (&memb);
1426 return 0;
316afdb1
NA
1427 }
1428 }
1429
1430 return (ctf_set_errno (ofp, ECTF_NOMEMBNAM));
1431}
1432
1433/* Return the array type, index, and size information for the specified ARRAY. */
1434
1435int
139633c3 1436ctf_array_info (ctf_dict_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
316afdb1 1437{
139633c3 1438 ctf_dict_t *ofp = fp;
316afdb1
NA
1439 const ctf_type_t *tp;
1440 const ctf_array_t *ap;
1441 const ctf_dtdef_t *dtd;
1442 ssize_t increment;
1443
1444 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1445 return -1; /* errno is set for us. */
316afdb1
NA
1446
1447 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ARRAY)
1448 return (ctf_set_errno (ofp, ECTF_NOTARRAY));
1449
1450 if ((dtd = ctf_dynamic_type (ofp, type)) != NULL)
534444b1
NA
1451 ap = (const ctf_array_t *) dtd->dtd_vlen;
1452 else
316afdb1 1453 {
534444b1
NA
1454 ctf_get_ctt_size (fp, tp, NULL, &increment);
1455 ap = (const ctf_array_t *) ((uintptr_t) tp + increment);
316afdb1 1456 }
316afdb1
NA
1457 arp->ctr_contents = ap->cta_contents;
1458 arp->ctr_index = ap->cta_index;
1459 arp->ctr_nelems = ap->cta_nelems;
1460
1461 return 0;
1462}
1463
1464/* Convert the specified value to the corresponding enum tag name, if a
1465 matching name can be found. Otherwise NULL is returned. */
1466
1467const char *
139633c3 1468ctf_enum_name (ctf_dict_t *fp, ctf_id_t type, int value)
316afdb1 1469{
139633c3 1470 ctf_dict_t *ofp = fp;
316afdb1
NA
1471 const ctf_type_t *tp;
1472 const ctf_enum_t *ep;
676c3ecb 1473 const ctf_dtdef_t *dtd;
316afdb1
NA
1474 ssize_t increment;
1475 uint32_t n;
1476
1477 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
1478 return NULL; /* errno is set for us. */
1479
1480 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1481 return NULL; /* errno is set for us. */
1482
1483 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1484 {
77d724a7 1485 ctf_set_errno (ofp, ECTF_NOTENUM);
316afdb1
NA
1486 return NULL;
1487 }
1488
77d724a7 1489 ctf_get_ctt_size (fp, tp, NULL, &increment);
316afdb1 1490
676c3ecb 1491 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
77d724a7 1492 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
676c3ecb 1493 else
77d724a7 1494 ep = (const ctf_enum_t *) dtd->dtd_vlen;
676c3ecb 1495
77d724a7
NA
1496 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1497 {
1498 if (ep->cte_value == value)
1499 return (ctf_strptr (fp, ep->cte_name));
316afdb1
NA
1500 }
1501
77d724a7 1502 ctf_set_errno (ofp, ECTF_NOENUMNAM);
316afdb1
NA
1503 return NULL;
1504}
1505
1506/* Convert the specified enum tag name to the corresponding value, if a
1507 matching name can be found. Otherwise CTF_ERR is returned. */
1508
1509int
77d724a7 1510ctf_enum_value (ctf_dict_t *fp, ctf_id_t type, const char *name, int *valp)
316afdb1 1511{
139633c3 1512 ctf_dict_t *ofp = fp;
316afdb1
NA
1513 const ctf_type_t *tp;
1514 const ctf_enum_t *ep;
676c3ecb 1515 const ctf_dtdef_t *dtd;
316afdb1
NA
1516 ssize_t increment;
1517 uint32_t n;
1518
1519 if ((type = ctf_type_resolve_unsliced (fp, type)) == CTF_ERR)
a0486bac 1520 return -1; /* errno is set for us. */
316afdb1
NA
1521
1522 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
a0486bac 1523 return -1; /* errno is set for us. */
316afdb1
NA
1524
1525 if (LCTF_INFO_KIND (fp, tp->ctt_info) != CTF_K_ENUM)
1526 {
1527 (void) ctf_set_errno (ofp, ECTF_NOTENUM);
a0486bac 1528 return -1;
316afdb1
NA
1529 }
1530
77d724a7 1531 ctf_get_ctt_size (fp, tp, NULL, &increment);
316afdb1 1532
676c3ecb 1533 if ((dtd = ctf_dynamic_type (ofp, type)) == NULL)
77d724a7 1534 ep = (const ctf_enum_t *) ((uintptr_t) tp + increment);
676c3ecb 1535 else
77d724a7 1536 ep = (const ctf_enum_t *) dtd->dtd_vlen;
676c3ecb 1537
77d724a7
NA
1538 for (n = LCTF_INFO_VLEN (fp, tp->ctt_info); n != 0; n--, ep++)
1539 {
1540 if (strcmp (ctf_strptr (fp, ep->cte_name), name) == 0)
676c3ecb 1541 {
77d724a7
NA
1542 if (valp != NULL)
1543 *valp = ep->cte_value;
1544 return 0;
316afdb1
NA
1545 }
1546 }
1547
77d724a7 1548 ctf_set_errno (ofp, ECTF_NOENUMNAM);
a0486bac 1549 return -1;
316afdb1
NA
1550}
1551
12a0b67d
NA
1552/* Given a type ID relating to a function type, return info on return types and
1553 arg counts for that function. */
1554
1555int
139633c3 1556ctf_func_type_info (ctf_dict_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
12a0b67d
NA
1557{
1558 const ctf_type_t *tp;
1559 uint32_t kind;
1560 const uint32_t *args;
676c3ecb 1561 const ctf_dtdef_t *dtd;
12a0b67d
NA
1562 ssize_t size, increment;
1563
1564 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1565 return -1; /* errno is set for us. */
1566
1567 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1568 return -1; /* errno is set for us. */
1569
1570 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1571 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1572
1573 if (kind != CTF_K_FUNCTION)
1574 return (ctf_set_errno (fp, ECTF_NOTFUNC));
1575
1576 fip->ctc_return = tp->ctt_type;
12a0b67d 1577 fip->ctc_flags = 0;
676c3ecb 1578 fip->ctc_argc = LCTF_INFO_VLEN (fp, tp->ctt_info);
12a0b67d 1579
676c3ecb
NA
1580 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1581 args = (uint32_t *) ((uintptr_t) tp + increment);
1582 else
81982d20 1583 args = (uint32_t *) dtd->dtd_vlen;
12a0b67d
NA
1584
1585 if (fip->ctc_argc != 0 && args[fip->ctc_argc - 1] == 0)
1586 {
1587 fip->ctc_flags |= CTF_FUNC_VARARG;
1588 fip->ctc_argc--;
1589 }
1590
1591 return 0;
1592}
1593
afd78bd6 1594/* Given a type ID relating to a function type, return the arguments for the
12a0b67d
NA
1595 function. */
1596
1597int
139633c3 1598ctf_func_type_args (ctf_dict_t *fp, ctf_id_t type, uint32_t argc, ctf_id_t *argv)
12a0b67d
NA
1599{
1600 const ctf_type_t *tp;
1601 const uint32_t *args;
676c3ecb 1602 const ctf_dtdef_t *dtd;
12a0b67d
NA
1603 ssize_t size, increment;
1604 ctf_funcinfo_t f;
1605
1606 if (ctf_func_type_info (fp, type, &f) < 0)
1607 return -1; /* errno is set for us. */
1608
1609 if ((type = ctf_type_resolve (fp, type)) == CTF_ERR)
1610 return -1; /* errno is set for us. */
1611
1612 if ((tp = ctf_lookup_by_id (&fp, type)) == NULL)
1613 return -1; /* errno is set for us. */
1614
1615 (void) ctf_get_ctt_size (fp, tp, &size, &increment);
1616
676c3ecb
NA
1617 if ((dtd = ctf_dynamic_type (fp, type)) == NULL)
1618 args = (uint32_t *) ((uintptr_t) tp + increment);
1619 else
81982d20 1620 args = (uint32_t *) dtd->dtd_vlen;
12a0b67d
NA
1621
1622 for (argc = MIN (argc, f.ctc_argc); argc != 0; argc--)
1623 *argv++ = *args++;
1624
1625 return 0;
1626}
1627
316afdb1
NA
1628/* Recursively visit the members of any type. This function is used as the
1629 engine for ctf_type_visit, below. We resolve the input type, recursively
1630 invoke ourself for each type member if the type is a struct or union, and
1631 then invoke the callback function on the current type. If any callback
1632 returns non-zero, we abort and percolate the error code back up to the top. */
1633
1634static int
139633c3 1635ctf_type_rvisit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func,
316afdb1
NA
1636 void *arg, const char *name, unsigned long offset, int depth)
1637{
1638 ctf_id_t otype = type;
1639 const ctf_type_t *tp;
676c3ecb 1640 const ctf_dtdef_t *dtd;
d7b1416e
NA
1641 unsigned char *vlen;
1642 ssize_t size, increment, vbytes;
1643 uint32_t kind, n, i = 0;
316afdb1
NA
1644 int rc;
1645
1646 if ((type = ctf_type_resolve (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 ((rc = func (name, otype, offset, depth, arg)) != 0)
1653 return rc;
1654
1655 kind = LCTF_INFO_KIND (fp, tp->ctt_info);
1656
1657 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
1658 return 0;
1659
d7b1416e 1660 ctf_get_ctt_size (fp, tp, &size, &increment);
316afdb1 1661
d7b1416e 1662 n = LCTF_INFO_VLEN (fp, tp->ctt_info);
08c428af 1663 if ((dtd = ctf_dynamic_type (fp, type)) != NULL)
316afdb1 1664 {
d7b1416e
NA
1665 vlen = dtd->dtd_vlen;
1666 vbytes = dtd->dtd_vlen_alloc;
316afdb1
NA
1667 }
1668 else
1669 {
d7b1416e
NA
1670 vlen = (unsigned char *) tp + increment;
1671 vbytes = LCTF_VBYTES (fp, kind, size, n);
1672 }
316afdb1 1673
d7b1416e
NA
1674 for (; n != 0; n--, i++)
1675 {
1676 ctf_lmember_t memb;
1677
1678 if (ctf_struct_member (fp, &memb, tp, vlen, vbytes, i) < 0)
1679 return -1; /* errno is set for us. */
1680
1681 if ((rc = ctf_type_rvisit (fp, memb.ctlm_type,
1682 func, arg, ctf_strptr (fp, memb.ctlm_name),
1683 offset + (unsigned long) CTF_LMEM_OFFSET (&memb),
1684 depth + 1)) != 0)
1685 return rc;
316afdb1
NA
1686 }
1687
1688 return 0;
1689}
1690
1691/* Recursively visit the members of any type. We pass the name, member
1692 type, and offset of each member to the specified callback function. */
1693int
139633c3 1694ctf_type_visit (ctf_dict_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
316afdb1
NA
1695{
1696 return (ctf_type_rvisit (fp, type, func, arg, "", 0, 0));
1697}
This page took 0.212341 seconds and 4 git commands to generate.