1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27 /*
28 * Copyright 2020 Joyent, Inc.
29 * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
30 */
31
32 #include <ctf_impl.h>
33 #include <sys/debug.h>
34
35 ssize_t
ctf_get_ctt_size(const ctf_file_t * fp,const ctf_type_t * tp,ssize_t * sizep,ssize_t * incrementp)36 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
37 ssize_t *incrementp)
38 {
39 ssize_t size, increment;
40
41 if (fp->ctf_version > CTF_VERSION_1 &&
42 tp->ctt_size == CTF_LSIZE_SENT) {
43 size = CTF_TYPE_LSIZE(tp);
44 increment = sizeof (ctf_type_t);
45 } else {
46 size = tp->ctt_size;
47 increment = sizeof (ctf_stype_t);
48 }
49
50 if (sizep)
51 *sizep = size;
52 if (incrementp)
53 *incrementp = increment;
54
55 return (size);
56 }
57
58 void
ctf_set_ctt_size(ctf_type_t * tp,ssize_t size)59 ctf_set_ctt_size(ctf_type_t *tp, ssize_t size)
60 {
61 if (size > CTF_MAX_SIZE) {
62 tp->ctt_size = CTF_LSIZE_SENT;
63 tp->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
64 tp->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
65 } else {
66 tp->ctt_size = (ushort_t)size;
67 }
68 }
69
70 /*
71 * Iterate over the members of a STRUCT or UNION. We pass the name, member
72 * type, and offset of each member to the specified callback function.
73 */
74 int
ctf_member_iter(ctf_file_t * fp,ctf_id_t type,ctf_member_f * func,void * arg)75 ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
76 {
77 ctf_file_t *ofp = fp;
78 const ctf_type_t *tp;
79 ssize_t size, increment;
80 uint_t kind, n;
81 int rc;
82
83 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
84 return (CTF_ERR); /* errno is set for us */
85
86 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
87 return (CTF_ERR); /* errno is set for us */
88
89 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
90 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
91
92 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
93 return (ctf_set_errno(ofp, ECTF_NOTSOU));
94
95 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
96 const ctf_member_t *mp = (const ctf_member_t *)
97 ((uintptr_t)tp + increment);
98
99 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
100 const char *name = ctf_strptr(fp, mp->ctm_name);
101 if ((rc = func(name, mp->ctm_type, mp->ctm_offset,
102 arg)) != 0)
103 return (rc);
104 }
105
106 } else {
107 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
108 ((uintptr_t)tp + increment);
109
110 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
111 const char *name = ctf_strptr(fp, lmp->ctlm_name);
112 if ((rc = func(name, lmp->ctlm_type,
113 (ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0)
114 return (rc);
115 }
116 }
117
118 return (0);
119 }
120
121 /*
122 * Iterate over the members of an ENUM. We pass the string name and associated
123 * integer value of each enum element to the specified callback function.
124 */
125 int
ctf_enum_iter(ctf_file_t * fp,ctf_id_t type,ctf_enum_f * func,void * arg)126 ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
127 {
128 ctf_file_t *ofp = fp;
129 const ctf_type_t *tp;
130 const ctf_enum_t *ep;
131 ssize_t increment;
132 uint_t n;
133 int rc;
134
135 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
136 return (CTF_ERR); /* errno is set for us */
137
138 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
139 return (CTF_ERR); /* errno is set for us */
140
141 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM)
142 return (ctf_set_errno(ofp, ECTF_NOTENUM));
143
144 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
145
146 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
147
148 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
149 const char *name = ctf_strptr(fp, ep->cte_name);
150 if ((rc = func(name, ep->cte_value, arg)) != 0)
151 return (rc);
152 }
153
154 return (0);
155 }
156
157 /*
158 * Iterate over every type in the given CTF container. If the user doesn't ask
159 * for all types, then we only give them the user visible, aka root, types. We
160 * pass the type ID of each type to the specified callback function.
161 */
162 int
ctf_type_iter(ctf_file_t * fp,boolean_t nonroot,ctf_type_f * func,void * arg)163 ctf_type_iter(ctf_file_t *fp, boolean_t nonroot, ctf_type_f *func, void *arg)
164 {
165 ctf_id_t id, max = fp->ctf_typemax;
166 int rc, child = (fp->ctf_flags & LCTF_CHILD);
167
168 for (id = 1; id <= max; id++) {
169 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
170 if ((nonroot || CTF_INFO_ISROOT(tp->ctt_info)) &&
171 (rc = func(CTF_INDEX_TO_TYPE(id, child),
172 CTF_INFO_ISROOT(tp->ctt_info), arg)) != 0)
173 return (rc);
174 }
175
176 return (0);
177 }
178
179 /*
180 * Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
181 * RESTRICT nodes until we reach a "base" type node. This is useful when
182 * we want to follow a type ID to a node that has members or a size. To guard
183 * against infinite loops, we implement simplified cycle detection and check
184 * each link against itself, the previous node, and the topmost node.
185 */
186 ctf_id_t
ctf_type_resolve(ctf_file_t * fp,ctf_id_t type)187 ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
188 {
189 ctf_id_t prev = type, otype = type;
190 ctf_file_t *ofp = fp;
191 const ctf_type_t *tp;
192
193 while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) {
194 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
195 case CTF_K_TYPEDEF:
196 case CTF_K_VOLATILE:
197 case CTF_K_CONST:
198 case CTF_K_RESTRICT:
199 if (tp->ctt_type == type || tp->ctt_type == otype ||
200 tp->ctt_type == prev) {
201 ctf_dprintf("type %ld cycle detected\n", otype);
202 return (ctf_set_errno(ofp, ECTF_CORRUPT));
203 }
204 prev = type;
205 type = tp->ctt_type;
206 break;
207 default:
208 return (type);
209 }
210 }
211
212 return (CTF_ERR); /* errno is set for us */
213 }
214
215 /*
216 * Format an integer type; if a vname is specified, we need to insert it prior
217 * to any bitfield ":24" suffix. This works out far simpler than figuring it
218 * out from scratch.
219 */
220 static const char *
ctf_format_int(ctf_decl_t * cd,const char * vname,const char * qname,const char * name)221 ctf_format_int(ctf_decl_t *cd, const char *vname, const char *qname,
222 const char *name)
223 {
224 const char *c;
225
226 if (vname == NULL) {
227 if (qname != NULL)
228 ctf_decl_sprintf(cd, "%s`%s", qname, name);
229 else
230 ctf_decl_sprintf(cd, "%s", name);
231 return (NULL);
232 }
233
234 if ((c = strchr(name, ':')) == NULL) {
235 ctf_decl_sprintf(cd, "%s", name);
236 return (vname);
237 }
238
239 /* "unsigned int mybits:23" */
240 ctf_decl_sprintf(cd, "%.*s %s%s", c - name, name, vname, c);
241 return (NULL);
242 }
243
244 static void
ctf_format_func(ctf_file_t * fp,ctf_decl_t * cd,const char * vname,ctf_id_t id,int want_func_args)245 ctf_format_func(ctf_file_t *fp, ctf_decl_t *cd,
246 const char *vname, ctf_id_t id, int want_func_args)
247 {
248 ctf_funcinfo_t fi;
249 /* We'll presume zone_create() is a bad example. */
250 ctf_id_t args[20];
251
252 ctf_decl_sprintf(cd, "%s(", vname == NULL ? "" : vname);
253
254 if (!want_func_args)
255 goto out;
256
257 if (ctf_func_info_by_id(fp, id, &fi) != 0)
258 goto out;
259
260 if (fi.ctc_argc > ARRAY_SIZE(args))
261 fi.ctc_argc = ARRAY_SIZE(args);
262
263 if (fi.ctc_argc == 0) {
264 ctf_decl_sprintf(cd, "void");
265 goto out;
266 }
267
268 if (ctf_func_args_by_id(fp, id, fi.ctc_argc, args) != 0)
269 goto out;
270
271 for (size_t i = 0; i < fi.ctc_argc; i++) {
272 char aname[512];
273
274 if (ctf_type_name(fp, args[i], aname, sizeof (aname)) == NULL)
275 (void) strlcpy(aname, "unknown_t", sizeof (aname));
276
277 ctf_decl_sprintf(cd, "%s%s", aname,
278 i + 1 == fi.ctc_argc ? "" : ", ");
279 }
280
281 if (fi.ctc_flags & CTF_FUNC_VARARG)
282 ctf_decl_sprintf(cd, "%s...", fi.ctc_argc == 0 ? "" : ", ");
283
284 out:
285 ctf_decl_sprintf(cd, ")");
286 }
287
288 /*
289 * Lookup the given type ID and print a string name for it into buf. Return the
290 * actual number of bytes (not including \0) needed to format the name.
291 *
292 * "vname" is an optional variable name or similar, so array suffix formatting,
293 * bitfields, and functions are C-correct. (This is not perfect, as can be seen
294 * in kiconv_ops_t.)
295 */
296 static ssize_t
ctf_type_qlname(ctf_file_t * fp,ctf_id_t type,char * buf,size_t len,const char * vname,const char * qname)297 ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
298 const char *vname, const char *qname)
299 {
300 int want_func_args = (vname != NULL);
301 ctf_decl_t cd;
302 ctf_decl_node_t *cdp;
303 ctf_decl_prec_t prec, lp, rp;
304 int ptr, arr;
305 uint_t k;
306
307 if (fp == NULL && type == CTF_ERR)
308 return (-1); /* simplify caller code by permitting CTF_ERR */
309
310 ctf_decl_init(&cd, buf, len);
311 ctf_decl_push(&cd, fp, type);
312
313 if (cd.cd_err != 0) {
314 ctf_decl_fini(&cd);
315 return (ctf_set_errno(fp, cd.cd_err));
316 }
317
318 /*
319 * If the type graph's order conflicts with lexical precedence order
320 * for pointers or arrays, then we need to surround the declarations at
321 * the corresponding lexical precedence with parentheses. This can
322 * result in either a parenthesized pointer (*) as in int (*)() or
323 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
324 */
325 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
326 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
327
328 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
329 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
330
331 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
332
333 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
334 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
335 cdp != NULL; cdp = ctf_list_next(cdp)) {
336
337 ctf_file_t *rfp = fp;
338 const ctf_type_t *tp =
339 ctf_lookup_by_id(&rfp, cdp->cd_type);
340 const char *name = ctf_strptr(rfp, tp->ctt_name);
341
342 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
343 ctf_decl_sprintf(&cd, " ");
344
345 if (lp == prec) {
346 ctf_decl_sprintf(&cd, "(");
347 lp = -1;
348 }
349
350 switch (cdp->cd_kind) {
351 case CTF_K_INTEGER:
352 vname = ctf_format_int(&cd, vname, qname, name);
353 break;
354 case CTF_K_FLOAT:
355 case CTF_K_TYPEDEF:
356 if (qname != NULL)
357 ctf_decl_sprintf(&cd, "%s`", qname);
358 ctf_decl_sprintf(&cd, "%s", name);
359 break;
360 case CTF_K_POINTER:
361 ctf_decl_sprintf(&cd, "*");
362 break;
363 case CTF_K_ARRAY:
364 ctf_decl_sprintf(&cd, "%s[%u]",
365 vname != NULL ? vname : "", cdp->cd_n);
366 vname = NULL;
367 break;
368 case CTF_K_FUNCTION:
369 ctf_format_func(fp, &cd, vname,
370 cdp->cd_type, want_func_args);
371 vname = NULL;
372 break;
373 case CTF_K_FORWARD:
374 switch (tp->ctt_type) {
375 case CTF_K_UNION:
376 ctf_decl_sprintf(&cd, "union ");
377 break;
378 case CTF_K_ENUM:
379 ctf_decl_sprintf(&cd, "enum ");
380 break;
381 case CTF_K_STRUCT:
382 default:
383 ctf_decl_sprintf(&cd, "struct ");
384 break;
385 }
386 if (qname != NULL)
387 ctf_decl_sprintf(&cd, "%s`", qname);
388 ctf_decl_sprintf(&cd, "%s", name);
389 break;
390 case CTF_K_STRUCT:
391 ctf_decl_sprintf(&cd, "struct ");
392 if (qname != NULL)
393 ctf_decl_sprintf(&cd, "%s`", qname);
394 ctf_decl_sprintf(&cd, "%s", name);
395 break;
396 case CTF_K_UNION:
397 ctf_decl_sprintf(&cd, "union ");
398 if (qname != NULL)
399 ctf_decl_sprintf(&cd, "%s`", qname);
400 ctf_decl_sprintf(&cd, "%s", name);
401 break;
402 case CTF_K_ENUM:
403 ctf_decl_sprintf(&cd, "enum ");
404 if (qname != NULL)
405 ctf_decl_sprintf(&cd, "%s`", qname);
406 ctf_decl_sprintf(&cd, "%s", name);
407 break;
408 case CTF_K_VOLATILE:
409 ctf_decl_sprintf(&cd, "volatile");
410 break;
411 case CTF_K_CONST:
412 ctf_decl_sprintf(&cd, "const");
413 break;
414 case CTF_K_RESTRICT:
415 ctf_decl_sprintf(&cd, "restrict");
416 break;
417 }
418
419 k = cdp->cd_kind;
420 }
421
422 if (rp == prec) {
423 /*
424 * Peek ahead: if we're going to hit a function,
425 * we want to insert its name now before this closing
426 * bracket.
427 */
428 if (vname != NULL && prec < CTF_PREC_FUNCTION) {
429 cdp = ctf_list_next(
430 &cd.cd_nodes[CTF_PREC_FUNCTION]);
431
432 if (cdp != NULL) {
433 ctf_decl_sprintf(&cd, "%s", vname);
434 vname = NULL;
435 }
436 }
437
438 ctf_decl_sprintf(&cd, ")");
439 }
440 }
441
442 if (vname != NULL)
443 ctf_decl_sprintf(&cd, " %s", vname);
444
445 if (cd.cd_len >= len)
446 (void) ctf_set_errno(fp, ECTF_NAMELEN);
447
448 ctf_decl_fini(&cd);
449 return (cd.cd_len);
450 }
451
452 ssize_t
ctf_type_lname(ctf_file_t * fp,ctf_id_t type,char * buf,size_t len)453 ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
454 {
455 return (ctf_type_qlname(fp, type, buf, len, NULL, NULL));
456 }
457
458 /*
459 * Lookup the given type ID and print a string name for it into buf. If buf
460 * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
461 */
462 char *
ctf_type_name(ctf_file_t * fp,ctf_id_t type,char * buf,size_t len)463 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
464 {
465 ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, NULL);
466 return (rv >= 0 && rv < len ? buf : NULL);
467 }
468
469 char *
ctf_type_qname(ctf_file_t * fp,ctf_id_t type,char * buf,size_t len,const char * qname)470 ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
471 const char *qname)
472 {
473 ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL, qname);
474 return (rv >= 0 && rv < len ? buf : NULL);
475 }
476
477 char *
ctf_type_cname(ctf_file_t * fp,ctf_id_t type,char * buf,size_t len,const char * cname)478 ctf_type_cname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
479 const char *cname)
480 {
481 ssize_t rv = ctf_type_qlname(fp, type, buf, len, cname, NULL);
482 return (rv >= 0 && rv < len ? buf : NULL);
483 }
484
485 /*
486 * Resolve the type down to a base type node, and then return the size
487 * of the type storage in bytes.
488 */
489 ssize_t
ctf_type_size(ctf_file_t * fp,ctf_id_t type)490 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
491 {
492 const ctf_type_t *tp;
493 ssize_t size;
494 ctf_arinfo_t ar;
495
496 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
497 return (-1); /* errno is set for us */
498
499 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
500 return (-1); /* errno is set for us */
501
502 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
503 case CTF_K_POINTER:
504 return (fp->ctf_dmodel->ctd_pointer);
505
506 case CTF_K_FUNCTION:
507 return (0); /* function size is only known by symtab */
508
509 case CTF_K_FORWARD:
510 return (0);
511
512 case CTF_K_ENUM:
513 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
514
515 case CTF_K_ARRAY:
516 /*
517 * Array size is not directly returned by stabs data. Instead,
518 * it defines the element type and requires the user to perform
519 * the multiplication. If ctf_get_ctt_size() returns zero, the
520 * current version of ctfconvert does not compute member sizes
521 * and we compute the size here on its behalf.
522 */
523 if ((size = ctf_get_ctt_size(fp, tp, NULL, NULL)) > 0)
524 return (size);
525
526 if (ctf_array_info(fp, type, &ar) == CTF_ERR ||
527 (size = ctf_type_size(fp, ar.ctr_contents)) == CTF_ERR)
528 return (-1); /* errno is set for us */
529
530 return (size * ar.ctr_nelems);
531 case CTF_K_STRUCT:
532 case CTF_K_UNION:
533 /*
534 * If we have a zero size, we may be in the process of adding a
535 * structure or union but having not called ctf_update() to deal
536 * with the circular dependencies in such structures and unions.
537 * To handle that case, if we get a size of zero from the ctt,
538 * we look up the dtdef and use its size instead.
539 */
540 size = ctf_get_ctt_size(fp, tp, NULL, NULL);
541 if (size == 0) {
542 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
543 if (dtd != NULL)
544 return (dtd->dtd_data.ctt_size);
545 }
546 return (size);
547 default:
548 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
549 }
550 }
551
552 /*
553 * Resolve the type down to a base type node, and then return the alignment
554 * needed for the type storage in bytes.
555 */
556 ssize_t
ctf_type_align(ctf_file_t * fp,ctf_id_t type)557 ctf_type_align(ctf_file_t *fp, ctf_id_t type)
558 {
559 const ctf_type_t *tp;
560 ctf_arinfo_t r;
561
562 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
563 return (-1); /* errno is set for us */
564
565 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
566 return (-1); /* errno is set for us */
567
568 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
569 case CTF_K_POINTER:
570 case CTF_K_FUNCTION:
571 return (fp->ctf_dmodel->ctd_pointer);
572
573 case CTF_K_ARRAY:
574 if (ctf_array_info(fp, type, &r) == CTF_ERR)
575 return (-1); /* errno is set for us */
576 return (ctf_type_align(fp, r.ctr_contents));
577
578 case CTF_K_STRUCT:
579 case CTF_K_UNION: {
580 uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info);
581 ssize_t size, increment;
582 size_t align = 0;
583 const void *vmp;
584
585 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
586 vmp = (uchar_t *)tp + increment;
587
588 if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT)
589 n = MIN(n, 1); /* only use first member for structs */
590
591 if (fp->ctf_version == CTF_VERSION_1 ||
592 size < CTF_LSTRUCT_THRESH) {
593 const ctf_member_t *mp = vmp;
594 for (; n != 0; n--, mp++) {
595 ssize_t am = ctf_type_align(fp, mp->ctm_type);
596 align = MAX(align, am);
597 }
598 } else {
599 const ctf_lmember_t *lmp = vmp;
600 for (; n != 0; n--, lmp++) {
601 ssize_t am = ctf_type_align(fp, lmp->ctlm_type);
602 align = MAX(align, am);
603 }
604 }
605
606 return (align);
607 }
608
609 case CTF_K_ENUM:
610 default:
611 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
612 }
613 }
614
615 /*
616 * Return the kind (CTF_K_* constant) for the specified type ID.
617 */
618 int
ctf_type_kind(ctf_file_t * fp,ctf_id_t type)619 ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
620 {
621 const ctf_type_t *tp;
622
623 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
624 return (CTF_ERR); /* errno is set for us */
625
626 return (LCTF_INFO_KIND(fp, tp->ctt_info));
627 }
628
629 /*
630 * If the type is one that directly references another type (such as POINTER),
631 * then return the ID of the type to which it refers.
632 */
633 ctf_id_t
ctf_type_reference(ctf_file_t * fp,ctf_id_t type)634 ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
635 {
636 ctf_file_t *ofp = fp;
637 const ctf_type_t *tp;
638
639 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
640 return (CTF_ERR); /* errno is set for us */
641
642 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
643 case CTF_K_POINTER:
644 case CTF_K_TYPEDEF:
645 case CTF_K_VOLATILE:
646 case CTF_K_CONST:
647 case CTF_K_RESTRICT:
648 return (tp->ctt_type);
649 default:
650 return (ctf_set_errno(ofp, ECTF_NOTREF));
651 }
652 }
653
654 /*
655 * Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
656 * pointer to the given type, see if we can compute a pointer to the type
657 * resulting from resolving the type down to its base type and use that
658 * instead. This helps with cases where the CTF data includes "struct foo *"
659 * but not "foo_t *" and the user accesses "foo_t *" in the debugger.
660 */
661 ctf_id_t
ctf_type_pointer(ctf_file_t * fp,ctf_id_t type)662 ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
663 {
664 ctf_file_t *ofp = fp;
665 ctf_id_t ntype;
666
667 if (ctf_lookup_by_id(&fp, type) == NULL)
668 return (CTF_ERR); /* errno is set for us */
669
670 if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
671 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
672
673 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
674 return (ctf_set_errno(ofp, ECTF_NOTYPE));
675
676 if (ctf_lookup_by_id(&fp, type) == NULL)
677 return (ctf_set_errno(ofp, ECTF_NOTYPE));
678
679 if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
680 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
681
682 return (ctf_set_errno(ofp, ECTF_NOTYPE));
683 }
684
685 /*
686 * Return the encoding for the specified INTEGER or FLOAT.
687 */
688 int
ctf_type_encoding(ctf_file_t * fp,ctf_id_t type,ctf_encoding_t * ep)689 ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
690 {
691 ctf_file_t *ofp = fp;
692 const ctf_type_t *tp;
693 ssize_t increment;
694 uint_t data;
695
696 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
697 return (CTF_ERR); /* errno is set for us */
698
699 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
700
701 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
702 case CTF_K_INTEGER:
703 data = *(const uint_t *)((uintptr_t)tp + increment);
704 ep->cte_format = CTF_INT_ENCODING(data);
705 ep->cte_offset = CTF_INT_OFFSET(data);
706 ep->cte_bits = CTF_INT_BITS(data);
707 break;
708 case CTF_K_FLOAT:
709 data = *(const uint_t *)((uintptr_t)tp + increment);
710 ep->cte_format = CTF_FP_ENCODING(data);
711 ep->cte_offset = CTF_FP_OFFSET(data);
712 ep->cte_bits = CTF_FP_BITS(data);
713 break;
714 default:
715 return (ctf_set_errno(ofp, ECTF_NOTINTFP));
716 }
717
718 return (0);
719 }
720
721 int
ctf_type_cmp(ctf_file_t * lfp,ctf_id_t ltype,ctf_file_t * rfp,ctf_id_t rtype)722 ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
723 {
724 int rval;
725
726 if (ltype < rtype)
727 rval = -1;
728 else if (ltype > rtype)
729 rval = 1;
730 else
731 rval = 0;
732
733 if (lfp == rfp)
734 return (rval);
735
736 if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
737 lfp = lfp->ctf_parent;
738
739 if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
740 rfp = rfp->ctf_parent;
741
742 if (lfp < rfp)
743 return (-1);
744
745 if (lfp > rfp)
746 return (1);
747
748 return (rval);
749 }
750
751 /*
752 * Return a boolean value indicating if two types are compatible integers or
753 * floating-pointer values. This function returns true if the two types are
754 * the same, or if they have the same ASCII name and encoding properties.
755 * This function could be extended to test for compatibility for other kinds.
756 */
757 int
ctf_type_compat(ctf_file_t * lfp,ctf_id_t ltype,ctf_file_t * rfp,ctf_id_t rtype)758 ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
759 ctf_file_t *rfp, ctf_id_t rtype)
760 {
761 const ctf_type_t *ltp, *rtp;
762 ctf_encoding_t le, re;
763 ctf_arinfo_t la, ra;
764 uint_t lkind, rkind;
765
766 if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)
767 return (1);
768
769 ltype = ctf_type_resolve(lfp, ltype);
770 lkind = ctf_type_kind(lfp, ltype);
771
772 rtype = ctf_type_resolve(rfp, rtype);
773 rkind = ctf_type_kind(rfp, rtype);
774
775 if (lkind != rkind ||
776 (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
777 (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
778 strcmp(ctf_strptr(lfp, ltp->ctt_name),
779 ctf_strptr(rfp, rtp->ctt_name)) != 0)
780 return (0);
781
782 switch (lkind) {
783 case CTF_K_INTEGER:
784 case CTF_K_FLOAT:
785 return (ctf_type_encoding(lfp, ltype, &le) == 0 &&
786 ctf_type_encoding(rfp, rtype, &re) == 0 &&
787 bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);
788 case CTF_K_POINTER:
789 return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),
790 rfp, ctf_type_reference(rfp, rtype)));
791 case CTF_K_ARRAY:
792 return (ctf_array_info(lfp, ltype, &la) == 0 &&
793 ctf_array_info(rfp, rtype, &ra) == 0 &&
794 la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(
795 lfp, la.ctr_contents, rfp, ra.ctr_contents) &&
796 ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));
797 case CTF_K_STRUCT:
798 case CTF_K_UNION:
799 return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));
800 case CTF_K_ENUM:
801 case CTF_K_FORWARD:
802 return (1); /* no other checks required for these type kinds */
803 default:
804 return (0); /* should not get here since we did a resolve */
805 }
806 }
807
808 /*
809 * Return the type and offset for a given member of a STRUCT or UNION.
810 */
811 int
ctf_member_info(ctf_file_t * fp,ctf_id_t type,const char * name,ctf_membinfo_t * mip)812 ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
813 ctf_membinfo_t *mip)
814 {
815 ctf_file_t *ofp = fp;
816 const ctf_type_t *tp;
817 ssize_t size, increment;
818 uint_t kind, n;
819
820 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
821 return (CTF_ERR); /* errno is set for us */
822
823 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
824 return (CTF_ERR); /* errno is set for us */
825
826 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
827 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
828
829 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
830 return (ctf_set_errno(ofp, ECTF_NOTSOU));
831
832 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
833 const ctf_member_t *mp = (const ctf_member_t *)
834 ((uintptr_t)tp + increment);
835
836 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
837 if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
838 mip->ctm_type = mp->ctm_type;
839 mip->ctm_offset = mp->ctm_offset;
840 return (0);
841 }
842 }
843 } else {
844 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
845 ((uintptr_t)tp + increment);
846
847 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
848 if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
849 mip->ctm_type = lmp->ctlm_type;
850 mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
851 return (0);
852 }
853 }
854 }
855
856 return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
857 }
858
859 /*
860 * Return the array type, index, and size information for the specified ARRAY.
861 */
862 int
ctf_array_info(ctf_file_t * fp,ctf_id_t type,ctf_arinfo_t * arp)863 ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
864 {
865 ctf_file_t *ofp = fp;
866 const ctf_type_t *tp;
867 const ctf_array_t *ap;
868 ssize_t increment;
869
870 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
871 return (CTF_ERR); /* errno is set for us */
872
873 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
874 return (ctf_set_errno(ofp, ECTF_NOTARRAY));
875
876 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
877
878 ap = (const ctf_array_t *)((uintptr_t)tp + increment);
879 arp->ctr_contents = ap->cta_contents;
880 arp->ctr_index = ap->cta_index;
881 arp->ctr_nelems = ap->cta_nelems;
882
883 return (0);
884 }
885
886 /*
887 * Convert the specified value to the corresponding enum member name, if a
888 * matching name can be found. Otherwise NULL is returned.
889 */
890 const char *
ctf_enum_name(ctf_file_t * fp,ctf_id_t type,int value)891 ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
892 {
893 ctf_file_t *ofp = fp;
894 const ctf_type_t *tp;
895 const ctf_enum_t *ep;
896 ssize_t increment;
897 uint_t n;
898
899 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
900 return (NULL); /* errno is set for us */
901
902 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
903 return (NULL); /* errno is set for us */
904
905 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
906 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
907 return (NULL);
908 }
909
910 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
911
912 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
913
914 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
915 if (ep->cte_value == value)
916 return (ctf_strptr(fp, ep->cte_name));
917 }
918
919 (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
920 return (NULL);
921 }
922
923 /*
924 * Convert the specified enum tag name to the corresponding value, if a
925 * matching name can be found. Otherwise CTF_ERR is returned.
926 */
927 int
ctf_enum_value(ctf_file_t * fp,ctf_id_t type,const char * name,int * valp)928 ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
929 {
930 ctf_file_t *ofp = fp;
931 const ctf_type_t *tp;
932 const ctf_enum_t *ep;
933 ssize_t size, increment;
934 uint_t n;
935
936 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
937 return (CTF_ERR); /* errno is set for us */
938
939 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
940 return (CTF_ERR); /* errno is set for us */
941
942 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
943 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
944 return (CTF_ERR);
945 }
946
947 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
948
949 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
950
951 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
952 if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
953 if (valp != NULL)
954 *valp = ep->cte_value;
955 return (0);
956 }
957 }
958
959 (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
960 return (CTF_ERR);
961 }
962
963 /*
964 * Recursively visit the members of any type. This function is used as the
965 * engine for ctf_type_visit, below. We resolve the input type, recursively
966 * invoke ourself for each type member if the type is a struct or union, and
967 * then invoke the callback function on the current type. If any callback
968 * returns non-zero, we abort and percolate the error code back up to the top.
969 */
970 static int
ctf_type_rvisit(ctf_file_t * fp,ctf_id_t type,ctf_visit_f * func,void * arg,const char * name,ulong_t offset,int depth)971 ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
972 const char *name, ulong_t offset, int depth)
973 {
974 ctf_id_t otype = type;
975 const ctf_type_t *tp;
976 ssize_t size, increment;
977 uint_t kind, n;
978 int rc;
979
980 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
981 return (CTF_ERR); /* errno is set for us */
982
983 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
984 return (CTF_ERR); /* errno is set for us */
985
986 if ((rc = func(name, otype, offset, depth, arg)) != 0)
987 return (rc);
988
989 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
990
991 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
992 return (0);
993
994 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
995
996 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
997 const ctf_member_t *mp = (const ctf_member_t *)
998 ((uintptr_t)tp + increment);
999
1000 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
1001 if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
1002 func, arg, ctf_strptr(fp, mp->ctm_name),
1003 offset + mp->ctm_offset, depth + 1)) != 0)
1004 return (rc);
1005 }
1006
1007 } else {
1008 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
1009 ((uintptr_t)tp + increment);
1010
1011 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
1012 if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
1013 func, arg, ctf_strptr(fp, lmp->ctlm_name),
1014 offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
1015 depth + 1)) != 0)
1016 return (rc);
1017 }
1018 }
1019
1020 return (0);
1021 }
1022
1023 /*
1024 * Recursively visit the members of any type. We pass the name, member
1025 * type, and offset of each member to the specified callback function.
1026 */
1027 int
ctf_type_visit(ctf_file_t * fp,ctf_id_t type,ctf_visit_f * func,void * arg)1028 ctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
1029 {
1030 return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));
1031 }
1032
1033 int
ctf_func_info_by_id(ctf_file_t * fp,ctf_id_t type,ctf_funcinfo_t * fip)1034 ctf_func_info_by_id(ctf_file_t *fp, ctf_id_t type, ctf_funcinfo_t *fip)
1035 {
1036 ctf_file_t *ofp = fp;
1037 const ctf_type_t *tp;
1038 const ushort_t *dp;
1039 int nargs;
1040 ssize_t increment;
1041
1042 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1043 return (CTF_ERR); /* errno is set for us */
1044
1045 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1046 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1047
1048 fip->ctc_return = tp->ctt_type;
1049 nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1050 fip->ctc_argc = nargs;
1051 fip->ctc_flags = 0;
1052
1053 /* dp should now point to the first argument */
1054 if (nargs != 0) {
1055 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1056 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1057 fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] + increment);
1058 if (dp[nargs - 1] == 0) {
1059 fip->ctc_flags |= CTF_FUNC_VARARG;
1060 fip->ctc_argc--;
1061 }
1062 }
1063
1064 return (0);
1065 }
1066
1067 int
ctf_func_args_by_id(ctf_file_t * fp,ctf_id_t type,uint_t argc,ctf_id_t * argv)1068 ctf_func_args_by_id(ctf_file_t *fp, ctf_id_t type, uint_t argc, ctf_id_t *argv)
1069 {
1070 ctf_file_t *ofp = fp;
1071 const ctf_type_t *tp;
1072 const ushort_t *dp;
1073 int nargs;
1074 ssize_t increment;
1075
1076 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
1077 return (CTF_ERR); /* errno is set for us */
1078
1079 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_FUNCTION)
1080 return (ctf_set_errno(ofp, ECTF_NOTFUNC));
1081
1082 nargs = LCTF_INFO_VLEN(fp, tp->ctt_info);
1083 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
1084 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1085 fp->ctf_txlate[CTF_TYPE_TO_INDEX(type)] +
1086 increment);
1087 if (nargs != 0 && dp[nargs - 1] == 0)
1088 nargs--;
1089
1090 for (nargs = MIN(argc, nargs); nargs != 0; nargs--)
1091 *argv++ = *dp++;
1092
1093 return (0);
1094 }
1095
1096 int
ctf_object_iter(ctf_file_t * fp,ctf_object_f * func,void * arg)1097 ctf_object_iter(ctf_file_t *fp, ctf_object_f *func, void *arg)
1098 {
1099 int i, ret;
1100 ctf_id_t id;
1101 uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1102 uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1103
1104 if (fp->ctf_symtab.cts_data == NULL)
1105 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1106
1107 for (i = 0; i < fp->ctf_nsyms; i++) {
1108 char *name;
1109 if (fp->ctf_sxlate[i] == -1u)
1110 continue;
1111 id = *(ushort_t *)((uintptr_t)fp->ctf_buf +
1112 fp->ctf_sxlate[i]);
1113
1114 /*
1115 * Validate whether or not we're looking at a data object as
1116 * oposed to a function.
1117 */
1118 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1119 const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1120 if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT)
1121 continue;
1122 if (fp->ctf_strtab.cts_data != NULL &&
1123 symp->st_name != 0)
1124 name = (char *)(strbase + symp->st_name);
1125 else
1126 name = NULL;
1127 } else {
1128 const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1129 if (ELF64_ST_TYPE(symp->st_info) != STT_OBJECT)
1130 continue;
1131 if (fp->ctf_strtab.cts_data != NULL &&
1132 symp->st_name != 0)
1133 name = (char *)(strbase + symp->st_name);
1134 else
1135 name = NULL;
1136 }
1137
1138 if ((ret = func(name, id, i, arg)) != 0)
1139 return (ret);
1140 }
1141
1142 return (0);
1143 }
1144
1145 int
ctf_function_iter(ctf_file_t * fp,ctf_function_f * func,void * arg)1146 ctf_function_iter(ctf_file_t *fp, ctf_function_f *func, void *arg)
1147 {
1148 int i, ret;
1149 uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1150 uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1151
1152 if (fp->ctf_symtab.cts_data == NULL)
1153 return (ctf_set_errno(fp, ECTF_NOSYMTAB));
1154
1155 for (i = 0; i < fp->ctf_nsyms; i++) {
1156 char *name;
1157 ushort_t info, *dp;
1158 ctf_funcinfo_t fi;
1159 if (fp->ctf_sxlate[i] == -1u)
1160 continue;
1161
1162 dp = (ushort_t *)((uintptr_t)fp->ctf_buf +
1163 fp->ctf_sxlate[i]);
1164 info = *dp;
1165 if (info == 0)
1166 continue;
1167
1168 /*
1169 * This may be a function or it may be a data object. We have to
1170 * consult the symbol table to be certain. Functions are encoded
1171 * with their info, data objects with their actual type.
1172 */
1173 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1174 const Elf32_Sym *symp = (Elf32_Sym *)symbase + i;
1175 if (ELF32_ST_TYPE(symp->st_info) != STT_FUNC)
1176 continue;
1177 if (fp->ctf_strtab.cts_data != NULL)
1178 name = (char *)(strbase + symp->st_name);
1179 else
1180 name = NULL;
1181 } else {
1182 const Elf64_Sym *symp = (Elf64_Sym *)symbase + i;
1183 if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC)
1184 continue;
1185 if (fp->ctf_strtab.cts_data != NULL)
1186 name = (char *)(strbase + symp->st_name);
1187 else
1188 name = NULL;
1189 }
1190
1191 if (LCTF_INFO_KIND(fp, info) != CTF_K_FUNCTION)
1192 continue;
1193 dp++;
1194 fi.ctc_return = *dp;
1195 dp++;
1196 fi.ctc_argc = LCTF_INFO_VLEN(fp, info);
1197 fi.ctc_flags = 0;
1198
1199 if (fi.ctc_argc != 0 && dp[fi.ctc_argc - 1] == 0) {
1200 fi.ctc_flags |= CTF_FUNC_VARARG;
1201 fi.ctc_argc--;
1202 }
1203
1204 if ((ret = func(name, i, &fi, arg)) != 0)
1205 return (ret);
1206
1207 }
1208
1209 return (0);
1210 }
1211
1212 char *
ctf_symbol_name(ctf_file_t * fp,ulong_t idx,char * buf,size_t len)1213 ctf_symbol_name(ctf_file_t *fp, ulong_t idx, char *buf, size_t len)
1214 {
1215 const char *name;
1216 uintptr_t symbase = (uintptr_t)fp->ctf_symtab.cts_data;
1217 uintptr_t strbase = (uintptr_t)fp->ctf_strtab.cts_data;
1218
1219 if (fp->ctf_symtab.cts_data == NULL) {
1220 (void) ctf_set_errno(fp, ECTF_NOSYMTAB);
1221 return (NULL);
1222 }
1223
1224 if (fp->ctf_strtab.cts_data == NULL) {
1225 (void) ctf_set_errno(fp, ECTF_STRTAB);
1226 return (NULL);
1227 }
1228
1229 if (idx > fp->ctf_nsyms) {
1230 (void) ctf_set_errno(fp, ECTF_NOTDATA);
1231 return (NULL);
1232 }
1233
1234 if (fp->ctf_symtab.cts_entsize == sizeof (Elf32_Sym)) {
1235 const Elf32_Sym *symp = (Elf32_Sym *)symbase + idx;
1236 if (ELF32_ST_TYPE(symp->st_info) != STT_OBJECT &&
1237 ELF32_ST_TYPE(symp->st_info) != STT_FUNC) {
1238 (void) ctf_set_errno(fp, ECTF_NOTDATA);
1239 return (NULL);
1240 }
1241 if (symp->st_name == 0) {
1242 (void) ctf_set_errno(fp, ENOENT);
1243 return (NULL);
1244 }
1245 name = (const char *)(strbase + symp->st_name);
1246 } else {
1247 const Elf64_Sym *symp = (Elf64_Sym *)symbase + idx;
1248 if (ELF64_ST_TYPE(symp->st_info) != STT_FUNC &&
1249 ELF64_ST_TYPE(symp->st_info) != STT_OBJECT) {
1250 (void) ctf_set_errno(fp, ECTF_NOTDATA);
1251 return (NULL);
1252 }
1253 if (symp->st_name == 0) {
1254 (void) ctf_set_errno(fp, ENOENT);
1255 return (NULL);
1256 }
1257 name = (const char *)(strbase + symp->st_name);
1258 }
1259
1260 (void) strlcpy(buf, name, len);
1261
1262 return (buf);
1263 }
1264
1265 int
ctf_string_iter(ctf_file_t * fp,ctf_string_f * func,void * arg)1266 ctf_string_iter(ctf_file_t *fp, ctf_string_f *func, void *arg)
1267 {
1268 int rc;
1269 const char *strp = fp->ctf_str[CTF_STRTAB_0].cts_strs;
1270 size_t strl = fp->ctf_str[CTF_STRTAB_0].cts_len;
1271
1272 while (strl > 0) {
1273 size_t len;
1274
1275 if ((rc = func(strp, arg)) != 0)
1276 return (rc);
1277
1278 len = strlen(strp) + 1;
1279 strl -= len;
1280 strp += len;
1281 }
1282
1283 return (0);
1284 }
1285
1286 /*
1287 * fp isn't strictly necessary at the moment. However, if we ever rev the file
1288 * format, the valid values for kind will change.
1289 */
1290 const char *
ctf_kind_name(ctf_file_t * fp,int kind)1291 ctf_kind_name(ctf_file_t *fp, int kind)
1292 {
1293 switch (kind) {
1294 case CTF_K_INTEGER:
1295 return ("integer");
1296 case CTF_K_FLOAT:
1297 return ("float");
1298 case CTF_K_POINTER:
1299 return ("pointer");
1300 case CTF_K_ARRAY:
1301 return ("array");
1302 case CTF_K_FUNCTION:
1303 return ("function");
1304 case CTF_K_STRUCT:
1305 return ("struct");
1306 case CTF_K_UNION:
1307 return ("union");
1308 case CTF_K_ENUM:
1309 return ("enum");
1310 case CTF_K_FORWARD:
1311 return ("forward");
1312 case CTF_K_TYPEDEF:
1313 return ("typedef");
1314 case CTF_K_VOLATILE:
1315 return ("volatile");
1316 case CTF_K_CONST:
1317 return ("const");
1318 case CTF_K_RESTRICT:
1319 return ("restrict");
1320 case CTF_K_UNKNOWN:
1321 default:
1322 return ("unknown");
1323 }
1324 }
1325
1326 ctf_id_t
ctf_max_id(ctf_file_t * fp)1327 ctf_max_id(ctf_file_t *fp)
1328 {
1329 int child = (fp->ctf_flags & LCTF_CHILD);
1330 return (fp->ctf_typemax + (child ? CTF_CHILD_START : 0));
1331 }
1332
1333 ulong_t
ctf_nr_syms(ctf_file_t * fp)1334 ctf_nr_syms(ctf_file_t *fp)
1335 {
1336 return (fp->ctf_nsyms);
1337 }
1338