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