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