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