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