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