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