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