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