Print this page
4474 DTrace Userland CTF Support
4475 DTrace userland Keyword
4476 DTrace tests should be better citizens
4479 pid provider types
4480 dof emulation missing checks
Reviewed by: Bryan Cantrill <bryan@joyent.com>
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 -#pragma ident "%Z%%M% %I% %E% SMI"
29 -
30 28 #include <ctf_impl.h>
31 29
32 30 ssize_t
33 31 ctf_get_ctt_size(const ctf_file_t *fp, const ctf_type_t *tp, ssize_t *sizep,
34 32 ssize_t *incrementp)
35 33 {
36 34 ssize_t size, increment;
37 35
38 36 if (fp->ctf_version > CTF_VERSION_1 &&
39 37 tp->ctt_size == CTF_LSIZE_SENT) {
40 38 size = CTF_TYPE_LSIZE(tp);
41 39 increment = sizeof (ctf_type_t);
42 40 } else {
43 41 size = tp->ctt_size;
44 42 increment = sizeof (ctf_stype_t);
45 43 }
46 44
47 45 if (sizep)
48 46 *sizep = size;
49 47 if (incrementp)
50 48 *incrementp = increment;
51 49
52 50 return (size);
53 51 }
54 52
55 53 /*
56 54 * Iterate over the members of a STRUCT or UNION. We pass the name, member
57 55 * type, and offset of each member to the specified callback function.
58 56 */
59 57 int
60 58 ctf_member_iter(ctf_file_t *fp, ctf_id_t type, ctf_member_f *func, void *arg)
61 59 {
62 60 ctf_file_t *ofp = fp;
63 61 const ctf_type_t *tp;
64 62 ssize_t size, increment;
65 63 uint_t kind, n;
66 64 int rc;
67 65
68 66 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
69 67 return (CTF_ERR); /* errno is set for us */
70 68
71 69 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
72 70 return (CTF_ERR); /* errno is set for us */
73 71
74 72 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
75 73 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
76 74
77 75 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
78 76 return (ctf_set_errno(ofp, ECTF_NOTSOU));
79 77
80 78 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
81 79 const ctf_member_t *mp = (const ctf_member_t *)
82 80 ((uintptr_t)tp + increment);
83 81
84 82 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
85 83 const char *name = ctf_strptr(fp, mp->ctm_name);
86 84 if ((rc = func(name, mp->ctm_type, mp->ctm_offset,
87 85 arg)) != 0)
88 86 return (rc);
89 87 }
90 88
91 89 } else {
92 90 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
93 91 ((uintptr_t)tp + increment);
94 92
95 93 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
96 94 const char *name = ctf_strptr(fp, lmp->ctlm_name);
97 95 if ((rc = func(name, lmp->ctlm_type,
98 96 (ulong_t)CTF_LMEM_OFFSET(lmp), arg)) != 0)
99 97 return (rc);
100 98 }
101 99 }
102 100
103 101 return (0);
104 102 }
105 103
106 104 /*
107 105 * Iterate over the members of an ENUM. We pass the string name and associated
108 106 * integer value of each enum element to the specified callback function.
109 107 */
110 108 int
111 109 ctf_enum_iter(ctf_file_t *fp, ctf_id_t type, ctf_enum_f *func, void *arg)
112 110 {
113 111 ctf_file_t *ofp = fp;
114 112 const ctf_type_t *tp;
115 113 const ctf_enum_t *ep;
116 114 ssize_t increment;
117 115 uint_t n;
118 116 int rc;
119 117
120 118 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
121 119 return (CTF_ERR); /* errno is set for us */
122 120
123 121 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
124 122 return (CTF_ERR); /* errno is set for us */
125 123
126 124 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM)
127 125 return (ctf_set_errno(ofp, ECTF_NOTENUM));
128 126
129 127 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
130 128
131 129 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
132 130
133 131 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
134 132 const char *name = ctf_strptr(fp, ep->cte_name);
135 133 if ((rc = func(name, ep->cte_value, arg)) != 0)
136 134 return (rc);
137 135 }
138 136
139 137 return (0);
140 138 }
141 139
142 140 /*
143 141 * Iterate over every root (user-visible) type in the given CTF container.
144 142 * We pass the type ID of each type to the specified callback function.
145 143 */
146 144 int
147 145 ctf_type_iter(ctf_file_t *fp, ctf_type_f *func, void *arg)
148 146 {
149 147 ctf_id_t id, max = fp->ctf_typemax;
150 148 int rc, child = (fp->ctf_flags & LCTF_CHILD);
151 149
152 150 for (id = 1; id <= max; id++) {
153 151 const ctf_type_t *tp = LCTF_INDEX_TO_TYPEPTR(fp, id);
154 152 if (CTF_INFO_ISROOT(tp->ctt_info) &&
155 153 (rc = func(CTF_INDEX_TO_TYPE(id, child), arg)) != 0)
156 154 return (rc);
157 155 }
158 156
159 157 return (0);
160 158 }
161 159
162 160 /*
163 161 * Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
164 162 * RESTRICT nodes until we reach a "base" type node. This is useful when
165 163 * we want to follow a type ID to a node that has members or a size. To guard
166 164 * against infinite loops, we implement simplified cycle detection and check
167 165 * each link against itself, the previous node, and the topmost node.
168 166 */
169 167 ctf_id_t
170 168 ctf_type_resolve(ctf_file_t *fp, ctf_id_t type)
171 169 {
172 170 ctf_id_t prev = type, otype = type;
173 171 ctf_file_t *ofp = fp;
174 172 const ctf_type_t *tp;
175 173
176 174 while ((tp = ctf_lookup_by_id(&fp, type)) != NULL) {
177 175 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
178 176 case CTF_K_TYPEDEF:
179 177 case CTF_K_VOLATILE:
180 178 case CTF_K_CONST:
181 179 case CTF_K_RESTRICT:
182 180 if (tp->ctt_type == type || tp->ctt_type == otype ||
183 181 tp->ctt_type == prev) {
184 182 ctf_dprintf("type %ld cycle detected\n", otype);
185 183 return (ctf_set_errno(ofp, ECTF_CORRUPT));
186 184 }
187 185 prev = type;
188 186 type = tp->ctt_type;
189 187 break;
190 188 default:
191 189 return (type);
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
192 190 }
193 191 }
194 192
195 193 return (CTF_ERR); /* errno is set for us */
196 194 }
197 195
198 196 /*
199 197 * Lookup the given type ID and print a string name for it into buf. Return
200 198 * the actual number of bytes (not including \0) needed to format the name.
201 199 */
202 -ssize_t
203 -ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
200 +static ssize_t
201 +ctf_type_qlname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
202 + const char *qname)
204 203 {
205 204 ctf_decl_t cd;
206 205 ctf_decl_node_t *cdp;
207 206 ctf_decl_prec_t prec, lp, rp;
208 207 int ptr, arr;
209 208 uint_t k;
210 209
211 210 if (fp == NULL && type == CTF_ERR)
212 211 return (-1); /* simplify caller code by permitting CTF_ERR */
213 212
214 213 ctf_decl_init(&cd, buf, len);
215 214 ctf_decl_push(&cd, fp, type);
216 215
217 216 if (cd.cd_err != 0) {
218 217 ctf_decl_fini(&cd);
219 218 return (ctf_set_errno(fp, cd.cd_err));
220 219 }
221 220
222 221 /*
223 222 * If the type graph's order conflicts with lexical precedence order
224 223 * for pointers or arrays, then we need to surround the declarations at
225 224 * the corresponding lexical precedence with parentheses. This can
226 225 * result in either a parenthesized pointer (*) as in int (*)() or
227 226 * int (*)[], or in a parenthesized pointer and array as in int (*[])().
228 227 */
229 228 ptr = cd.cd_order[CTF_PREC_POINTER] > CTF_PREC_POINTER;
230 229 arr = cd.cd_order[CTF_PREC_ARRAY] > CTF_PREC_ARRAY;
231 230
232 231 rp = arr ? CTF_PREC_ARRAY : ptr ? CTF_PREC_POINTER : -1;
233 232 lp = ptr ? CTF_PREC_POINTER : arr ? CTF_PREC_ARRAY : -1;
234 233
235 234 k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
236 235
237 236 for (prec = CTF_PREC_BASE; prec < CTF_PREC_MAX; prec++) {
238 237 for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
239 238 cdp != NULL; cdp = ctf_list_next(cdp)) {
240 239
241 240 ctf_file_t *rfp = fp;
242 241 const ctf_type_t *tp =
243 242 ctf_lookup_by_id(&rfp, cdp->cd_type);
244 243 const char *name = ctf_strptr(rfp, tp->ctt_name);
245 244
246 245 if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
247 246 ctf_decl_sprintf(&cd, " ");
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
248 247
249 248 if (lp == prec) {
250 249 ctf_decl_sprintf(&cd, "(");
251 250 lp = -1;
252 251 }
253 252
254 253 switch (cdp->cd_kind) {
255 254 case CTF_K_INTEGER:
256 255 case CTF_K_FLOAT:
257 256 case CTF_K_TYPEDEF:
257 + if (qname != NULL)
258 + ctf_decl_sprintf(&cd, "%s`", qname);
258 259 ctf_decl_sprintf(&cd, "%s", name);
259 260 break;
260 261 case CTF_K_POINTER:
261 262 ctf_decl_sprintf(&cd, "*");
262 263 break;
263 264 case CTF_K_ARRAY:
264 265 ctf_decl_sprintf(&cd, "[%u]", cdp->cd_n);
265 266 break;
266 267 case CTF_K_FUNCTION:
267 268 ctf_decl_sprintf(&cd, "()");
268 269 break;
269 270 case CTF_K_STRUCT:
270 271 case CTF_K_FORWARD:
271 - ctf_decl_sprintf(&cd, "struct %s", name);
272 + ctf_decl_sprintf(&cd, "struct ");
273 + if (qname != NULL)
274 + ctf_decl_sprintf(&cd, "%s`", qname);
275 + ctf_decl_sprintf(&cd, "%s", name);
272 276 break;
273 277 case CTF_K_UNION:
274 - ctf_decl_sprintf(&cd, "union %s", name);
278 + ctf_decl_sprintf(&cd, "union ");
279 + if (qname != NULL)
280 + ctf_decl_sprintf(&cd, "%s`", qname);
281 + ctf_decl_sprintf(&cd, "%s", name);
275 282 break;
276 283 case CTF_K_ENUM:
277 - ctf_decl_sprintf(&cd, "enum %s", name);
284 + ctf_decl_sprintf(&cd, "enum ");
285 + if (qname != NULL)
286 + ctf_decl_sprintf(&cd, "%s`", qname);
287 + ctf_decl_sprintf(&cd, "%s", name);
278 288 break;
279 289 case CTF_K_VOLATILE:
280 290 ctf_decl_sprintf(&cd, "volatile");
281 291 break;
282 292 case CTF_K_CONST:
283 293 ctf_decl_sprintf(&cd, "const");
284 294 break;
285 295 case CTF_K_RESTRICT:
286 296 ctf_decl_sprintf(&cd, "restrict");
287 297 break;
288 298 }
289 299
290 300 k = cdp->cd_kind;
291 301 }
292 302
293 303 if (rp == prec)
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
294 304 ctf_decl_sprintf(&cd, ")");
295 305 }
296 306
297 307 if (cd.cd_len >= len)
298 308 (void) ctf_set_errno(fp, ECTF_NAMELEN);
299 309
300 310 ctf_decl_fini(&cd);
301 311 return (cd.cd_len);
302 312 }
303 313
314 +ssize_t
315 +ctf_type_lname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
316 +{
317 + return (ctf_type_qlname(fp, type, buf, len, NULL));
318 +}
319 +
304 320 /*
305 321 * Lookup the given type ID and print a string name for it into buf. If buf
306 322 * is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
307 323 */
308 324 char *
309 325 ctf_type_name(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len)
310 326 {
311 - ssize_t rv = ctf_type_lname(fp, type, buf, len);
327 + ssize_t rv = ctf_type_qlname(fp, type, buf, len, NULL);
328 + return (rv >= 0 && rv < len ? buf : NULL);
329 +}
330 +
331 +char *
332 +ctf_type_qname(ctf_file_t *fp, ctf_id_t type, char *buf, size_t len,
333 + const char *qname)
334 +{
335 + ssize_t rv = ctf_type_qlname(fp, type, buf, len, qname);
312 336 return (rv >= 0 && rv < len ? buf : NULL);
313 337 }
314 338
339 +
315 340 /*
316 341 * Resolve the type down to a base type node, and then return the size
317 342 * of the type storage in bytes.
318 343 */
319 344 ssize_t
320 345 ctf_type_size(ctf_file_t *fp, ctf_id_t type)
321 346 {
322 347 const ctf_type_t *tp;
323 348 ssize_t size;
324 349 ctf_arinfo_t ar;
325 350
326 351 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
327 352 return (-1); /* errno is set for us */
328 353
329 354 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
330 355 return (-1); /* errno is set for us */
331 356
332 357 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
333 358 case CTF_K_POINTER:
334 359 return (fp->ctf_dmodel->ctd_pointer);
335 360
336 361 case CTF_K_FUNCTION:
337 362 return (0); /* function size is only known by symtab */
338 363
339 364 case CTF_K_ENUM:
340 365 return (fp->ctf_dmodel->ctd_int);
341 366
342 367 case CTF_K_ARRAY:
343 368 /*
344 369 * Array size is not directly returned by stabs data. Instead,
345 370 * it defines the element type and requires the user to perform
346 371 * the multiplication. If ctf_get_ctt_size() returns zero, the
347 372 * current version of ctfconvert does not compute member sizes
348 373 * and we compute the size here on its behalf.
349 374 */
350 375 if ((size = ctf_get_ctt_size(fp, tp, NULL, NULL)) > 0)
351 376 return (size);
352 377
353 378 if (ctf_array_info(fp, type, &ar) == CTF_ERR ||
354 379 (size = ctf_type_size(fp, ar.ctr_contents)) == CTF_ERR)
355 380 return (-1); /* errno is set for us */
356 381
357 382 return (size * ar.ctr_nelems);
358 383
359 384 default:
360 385 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
361 386 }
362 387 }
363 388
364 389 /*
365 390 * Resolve the type down to a base type node, and then return the alignment
366 391 * needed for the type storage in bytes.
367 392 */
368 393 ssize_t
369 394 ctf_type_align(ctf_file_t *fp, ctf_id_t type)
370 395 {
371 396 const ctf_type_t *tp;
372 397 ctf_arinfo_t r;
373 398
374 399 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
375 400 return (-1); /* errno is set for us */
376 401
377 402 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
378 403 return (-1); /* errno is set for us */
379 404
380 405 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
381 406 case CTF_K_POINTER:
382 407 case CTF_K_FUNCTION:
383 408 return (fp->ctf_dmodel->ctd_pointer);
384 409
385 410 case CTF_K_ARRAY:
386 411 if (ctf_array_info(fp, type, &r) == CTF_ERR)
387 412 return (-1); /* errno is set for us */
388 413 return (ctf_type_align(fp, r.ctr_contents));
389 414
390 415 case CTF_K_STRUCT:
391 416 case CTF_K_UNION: {
392 417 uint_t n = LCTF_INFO_VLEN(fp, tp->ctt_info);
393 418 ssize_t size, increment;
394 419 size_t align = 0;
395 420 const void *vmp;
396 421
397 422 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
398 423 vmp = (uchar_t *)tp + increment;
399 424
400 425 if (LCTF_INFO_KIND(fp, tp->ctt_info) == CTF_K_STRUCT)
401 426 n = MIN(n, 1); /* only use first member for structs */
402 427
403 428 if (fp->ctf_version == CTF_VERSION_1 ||
404 429 size < CTF_LSTRUCT_THRESH) {
405 430 const ctf_member_t *mp = vmp;
406 431 for (; n != 0; n--, mp++) {
407 432 ssize_t am = ctf_type_align(fp, mp->ctm_type);
408 433 align = MAX(align, am);
409 434 }
410 435 } else {
411 436 const ctf_lmember_t *lmp = vmp;
412 437 for (; n != 0; n--, lmp++) {
413 438 ssize_t am = ctf_type_align(fp, lmp->ctlm_type);
414 439 align = MAX(align, am);
415 440 }
416 441 }
417 442
418 443 return (align);
419 444 }
420 445
421 446 case CTF_K_ENUM:
422 447 return (fp->ctf_dmodel->ctd_int);
423 448
424 449 default:
425 450 return (ctf_get_ctt_size(fp, tp, NULL, NULL));
426 451 }
427 452 }
428 453
429 454 /*
430 455 * Return the kind (CTF_K_* constant) for the specified type ID.
431 456 */
432 457 int
433 458 ctf_type_kind(ctf_file_t *fp, ctf_id_t type)
434 459 {
435 460 const ctf_type_t *tp;
436 461
437 462 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
438 463 return (CTF_ERR); /* errno is set for us */
439 464
440 465 return (LCTF_INFO_KIND(fp, tp->ctt_info));
441 466 }
442 467
443 468 /*
444 469 * If the type is one that directly references another type (such as POINTER),
445 470 * then return the ID of the type to which it refers.
446 471 */
447 472 ctf_id_t
448 473 ctf_type_reference(ctf_file_t *fp, ctf_id_t type)
449 474 {
450 475 ctf_file_t *ofp = fp;
451 476 const ctf_type_t *tp;
452 477
453 478 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
454 479 return (CTF_ERR); /* errno is set for us */
455 480
456 481 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
457 482 case CTF_K_POINTER:
458 483 case CTF_K_TYPEDEF:
459 484 case CTF_K_VOLATILE:
460 485 case CTF_K_CONST:
461 486 case CTF_K_RESTRICT:
462 487 return (tp->ctt_type);
463 488 default:
464 489 return (ctf_set_errno(ofp, ECTF_NOTREF));
465 490 }
466 491 }
467 492
468 493 /*
469 494 * Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
470 495 * pointer to the given type, see if we can compute a pointer to the type
471 496 * resulting from resolving the type down to its base type and use that
472 497 * instead. This helps with cases where the CTF data includes "struct foo *"
473 498 * but not "foo_t *" and the user accesses "foo_t *" in the debugger.
474 499 */
475 500 ctf_id_t
476 501 ctf_type_pointer(ctf_file_t *fp, ctf_id_t type)
477 502 {
478 503 ctf_file_t *ofp = fp;
479 504 ctf_id_t ntype;
480 505
481 506 if (ctf_lookup_by_id(&fp, type) == NULL)
482 507 return (CTF_ERR); /* errno is set for us */
483 508
484 509 if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
485 510 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
486 511
487 512 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
488 513 return (ctf_set_errno(ofp, ECTF_NOTYPE));
489 514
490 515 if (ctf_lookup_by_id(&fp, type) == NULL)
491 516 return (ctf_set_errno(ofp, ECTF_NOTYPE));
492 517
493 518 if ((ntype = fp->ctf_ptrtab[CTF_TYPE_TO_INDEX(type)]) != 0)
494 519 return (CTF_INDEX_TO_TYPE(ntype, (fp->ctf_flags & LCTF_CHILD)));
495 520
496 521 return (ctf_set_errno(ofp, ECTF_NOTYPE));
497 522 }
498 523
499 524 /*
500 525 * Return the encoding for the specified INTEGER or FLOAT.
501 526 */
502 527 int
503 528 ctf_type_encoding(ctf_file_t *fp, ctf_id_t type, ctf_encoding_t *ep)
504 529 {
505 530 ctf_file_t *ofp = fp;
506 531 const ctf_type_t *tp;
507 532 ssize_t increment;
508 533 uint_t data;
509 534
510 535 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
511 536 return (CTF_ERR); /* errno is set for us */
512 537
513 538 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
514 539
515 540 switch (LCTF_INFO_KIND(fp, tp->ctt_info)) {
516 541 case CTF_K_INTEGER:
517 542 data = *(const uint_t *)((uintptr_t)tp + increment);
518 543 ep->cte_format = CTF_INT_ENCODING(data);
519 544 ep->cte_offset = CTF_INT_OFFSET(data);
520 545 ep->cte_bits = CTF_INT_BITS(data);
521 546 break;
522 547 case CTF_K_FLOAT:
523 548 data = *(const uint_t *)((uintptr_t)tp + increment);
524 549 ep->cte_format = CTF_FP_ENCODING(data);
525 550 ep->cte_offset = CTF_FP_OFFSET(data);
526 551 ep->cte_bits = CTF_FP_BITS(data);
527 552 break;
528 553 default:
529 554 return (ctf_set_errno(ofp, ECTF_NOTINTFP));
530 555 }
531 556
532 557 return (0);
533 558 }
534 559
535 560 int
536 561 ctf_type_cmp(ctf_file_t *lfp, ctf_id_t ltype, ctf_file_t *rfp, ctf_id_t rtype)
537 562 {
538 563 int rval;
539 564
540 565 if (ltype < rtype)
541 566 rval = -1;
542 567 else if (ltype > rtype)
543 568 rval = 1;
544 569 else
545 570 rval = 0;
546 571
547 572 if (lfp == rfp)
548 573 return (rval);
549 574
550 575 if (CTF_TYPE_ISPARENT(ltype) && lfp->ctf_parent != NULL)
551 576 lfp = lfp->ctf_parent;
552 577
553 578 if (CTF_TYPE_ISPARENT(rtype) && rfp->ctf_parent != NULL)
554 579 rfp = rfp->ctf_parent;
555 580
556 581 if (lfp < rfp)
557 582 return (-1);
558 583
559 584 if (lfp > rfp)
560 585 return (1);
561 586
562 587 return (rval);
563 588 }
564 589
565 590 /*
566 591 * Return a boolean value indicating if two types are compatible integers or
567 592 * floating-pointer values. This function returns true if the two types are
568 593 * the same, or if they have the same ASCII name and encoding properties.
569 594 * This function could be extended to test for compatibility for other kinds.
570 595 */
571 596 int
572 597 ctf_type_compat(ctf_file_t *lfp, ctf_id_t ltype,
573 598 ctf_file_t *rfp, ctf_id_t rtype)
574 599 {
575 600 const ctf_type_t *ltp, *rtp;
576 601 ctf_encoding_t le, re;
577 602 ctf_arinfo_t la, ra;
578 603 uint_t lkind, rkind;
579 604
580 605 if (ctf_type_cmp(lfp, ltype, rfp, rtype) == 0)
581 606 return (1);
582 607
583 608 ltype = ctf_type_resolve(lfp, ltype);
584 609 lkind = ctf_type_kind(lfp, ltype);
585 610
586 611 rtype = ctf_type_resolve(rfp, rtype);
587 612 rkind = ctf_type_kind(rfp, rtype);
588 613
589 614 if (lkind != rkind ||
590 615 (ltp = ctf_lookup_by_id(&lfp, ltype)) == NULL ||
591 616 (rtp = ctf_lookup_by_id(&rfp, rtype)) == NULL ||
592 617 strcmp(ctf_strptr(lfp, ltp->ctt_name),
593 618 ctf_strptr(rfp, rtp->ctt_name)) != 0)
594 619 return (0);
595 620
596 621 switch (lkind) {
597 622 case CTF_K_INTEGER:
598 623 case CTF_K_FLOAT:
599 624 return (ctf_type_encoding(lfp, ltype, &le) == 0 &&
600 625 ctf_type_encoding(rfp, rtype, &re) == 0 &&
601 626 bcmp(&le, &re, sizeof (ctf_encoding_t)) == 0);
602 627 case CTF_K_POINTER:
603 628 return (ctf_type_compat(lfp, ctf_type_reference(lfp, ltype),
604 629 rfp, ctf_type_reference(rfp, rtype)));
605 630 case CTF_K_ARRAY:
606 631 return (ctf_array_info(lfp, ltype, &la) == 0 &&
607 632 ctf_array_info(rfp, rtype, &ra) == 0 &&
608 633 la.ctr_nelems == ra.ctr_nelems && ctf_type_compat(
609 634 lfp, la.ctr_contents, rfp, ra.ctr_contents) &&
610 635 ctf_type_compat(lfp, la.ctr_index, rfp, ra.ctr_index));
611 636 case CTF_K_STRUCT:
612 637 case CTF_K_UNION:
613 638 return (ctf_type_size(lfp, ltype) == ctf_type_size(rfp, rtype));
614 639 case CTF_K_ENUM:
615 640 case CTF_K_FORWARD:
616 641 return (1); /* no other checks required for these type kinds */
617 642 default:
618 643 return (0); /* should not get here since we did a resolve */
619 644 }
620 645 }
621 646
622 647 /*
623 648 * Return the type and offset for a given member of a STRUCT or UNION.
624 649 */
625 650 int
626 651 ctf_member_info(ctf_file_t *fp, ctf_id_t type, const char *name,
627 652 ctf_membinfo_t *mip)
628 653 {
629 654 ctf_file_t *ofp = fp;
630 655 const ctf_type_t *tp;
631 656 ssize_t size, increment;
632 657 uint_t kind, n;
633 658
634 659 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
635 660 return (CTF_ERR); /* errno is set for us */
636 661
637 662 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
638 663 return (CTF_ERR); /* errno is set for us */
639 664
640 665 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
641 666 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
642 667
643 668 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
644 669 return (ctf_set_errno(ofp, ECTF_NOTSOU));
645 670
646 671 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
647 672 const ctf_member_t *mp = (const ctf_member_t *)
648 673 ((uintptr_t)tp + increment);
649 674
650 675 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
651 676 if (strcmp(ctf_strptr(fp, mp->ctm_name), name) == 0) {
652 677 mip->ctm_type = mp->ctm_type;
653 678 mip->ctm_offset = mp->ctm_offset;
654 679 return (0);
655 680 }
656 681 }
657 682 } else {
658 683 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
659 684 ((uintptr_t)tp + increment);
660 685
661 686 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
662 687 if (strcmp(ctf_strptr(fp, lmp->ctlm_name), name) == 0) {
663 688 mip->ctm_type = lmp->ctlm_type;
664 689 mip->ctm_offset = (ulong_t)CTF_LMEM_OFFSET(lmp);
665 690 return (0);
666 691 }
667 692 }
668 693 }
669 694
670 695 return (ctf_set_errno(ofp, ECTF_NOMEMBNAM));
671 696 }
672 697
673 698 /*
674 699 * Return the array type, index, and size information for the specified ARRAY.
675 700 */
676 701 int
677 702 ctf_array_info(ctf_file_t *fp, ctf_id_t type, ctf_arinfo_t *arp)
678 703 {
679 704 ctf_file_t *ofp = fp;
680 705 const ctf_type_t *tp;
681 706 const ctf_array_t *ap;
682 707 ssize_t increment;
683 708
684 709 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
685 710 return (CTF_ERR); /* errno is set for us */
686 711
687 712 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ARRAY)
688 713 return (ctf_set_errno(ofp, ECTF_NOTARRAY));
689 714
690 715 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
691 716
692 717 ap = (const ctf_array_t *)((uintptr_t)tp + increment);
693 718 arp->ctr_contents = ap->cta_contents;
694 719 arp->ctr_index = ap->cta_index;
695 720 arp->ctr_nelems = ap->cta_nelems;
696 721
697 722 return (0);
698 723 }
699 724
700 725 /*
701 726 * Convert the specified value to the corresponding enum member name, if a
702 727 * matching name can be found. Otherwise NULL is returned.
703 728 */
704 729 const char *
705 730 ctf_enum_name(ctf_file_t *fp, ctf_id_t type, int value)
706 731 {
707 732 ctf_file_t *ofp = fp;
708 733 const ctf_type_t *tp;
709 734 const ctf_enum_t *ep;
710 735 ssize_t increment;
711 736 uint_t n;
712 737
713 738 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
714 739 return (NULL); /* errno is set for us */
715 740
716 741 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
717 742 return (NULL); /* errno is set for us */
718 743
719 744 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
720 745 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
721 746 return (NULL);
722 747 }
723 748
724 749 (void) ctf_get_ctt_size(fp, tp, NULL, &increment);
725 750
726 751 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
727 752
728 753 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
729 754 if (ep->cte_value == value)
730 755 return (ctf_strptr(fp, ep->cte_name));
731 756 }
732 757
733 758 (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
734 759 return (NULL);
735 760 }
736 761
737 762 /*
738 763 * Convert the specified enum tag name to the corresponding value, if a
739 764 * matching name can be found. Otherwise CTF_ERR is returned.
740 765 */
741 766 int
742 767 ctf_enum_value(ctf_file_t *fp, ctf_id_t type, const char *name, int *valp)
743 768 {
744 769 ctf_file_t *ofp = fp;
745 770 const ctf_type_t *tp;
746 771 const ctf_enum_t *ep;
747 772 ssize_t size, increment;
748 773 uint_t n;
749 774
750 775 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
751 776 return (CTF_ERR); /* errno is set for us */
752 777
753 778 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
754 779 return (CTF_ERR); /* errno is set for us */
755 780
756 781 if (LCTF_INFO_KIND(fp, tp->ctt_info) != CTF_K_ENUM) {
757 782 (void) ctf_set_errno(ofp, ECTF_NOTENUM);
758 783 return (CTF_ERR);
759 784 }
760 785
761 786 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
762 787
763 788 ep = (const ctf_enum_t *)((uintptr_t)tp + increment);
764 789
765 790 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, ep++) {
766 791 if (strcmp(ctf_strptr(fp, ep->cte_name), name) == 0) {
767 792 if (valp != NULL)
768 793 *valp = ep->cte_value;
769 794 return (0);
770 795 }
771 796 }
772 797
773 798 (void) ctf_set_errno(ofp, ECTF_NOENUMNAM);
774 799 return (CTF_ERR);
775 800 }
776 801
777 802 /*
778 803 * Recursively visit the members of any type. This function is used as the
779 804 * engine for ctf_type_visit, below. We resolve the input type, recursively
780 805 * invoke ourself for each type member if the type is a struct or union, and
781 806 * then invoke the callback function on the current type. If any callback
782 807 * returns non-zero, we abort and percolate the error code back up to the top.
783 808 */
784 809 static int
785 810 ctf_type_rvisit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg,
786 811 const char *name, ulong_t offset, int depth)
787 812 {
788 813 ctf_id_t otype = type;
789 814 const ctf_type_t *tp;
790 815 ssize_t size, increment;
791 816 uint_t kind, n;
792 817 int rc;
793 818
794 819 if ((type = ctf_type_resolve(fp, type)) == CTF_ERR)
795 820 return (CTF_ERR); /* errno is set for us */
796 821
797 822 if ((tp = ctf_lookup_by_id(&fp, type)) == NULL)
798 823 return (CTF_ERR); /* errno is set for us */
799 824
800 825 if ((rc = func(name, otype, offset, depth, arg)) != 0)
801 826 return (rc);
802 827
803 828 kind = LCTF_INFO_KIND(fp, tp->ctt_info);
804 829
805 830 if (kind != CTF_K_STRUCT && kind != CTF_K_UNION)
806 831 return (0);
807 832
808 833 (void) ctf_get_ctt_size(fp, tp, &size, &increment);
809 834
810 835 if (fp->ctf_version == CTF_VERSION_1 || size < CTF_LSTRUCT_THRESH) {
811 836 const ctf_member_t *mp = (const ctf_member_t *)
812 837 ((uintptr_t)tp + increment);
813 838
814 839 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, mp++) {
815 840 if ((rc = ctf_type_rvisit(fp, mp->ctm_type,
816 841 func, arg, ctf_strptr(fp, mp->ctm_name),
817 842 offset + mp->ctm_offset, depth + 1)) != 0)
818 843 return (rc);
819 844 }
820 845
821 846 } else {
822 847 const ctf_lmember_t *lmp = (const ctf_lmember_t *)
823 848 ((uintptr_t)tp + increment);
824 849
825 850 for (n = LCTF_INFO_VLEN(fp, tp->ctt_info); n != 0; n--, lmp++) {
826 851 if ((rc = ctf_type_rvisit(fp, lmp->ctlm_type,
827 852 func, arg, ctf_strptr(fp, lmp->ctlm_name),
828 853 offset + (ulong_t)CTF_LMEM_OFFSET(lmp),
829 854 depth + 1)) != 0)
830 855 return (rc);
831 856 }
832 857 }
833 858
834 859 return (0);
835 860 }
836 861
837 862 /*
838 863 * Recursively visit the members of any type. We pass the name, member
839 864 * type, and offset of each member to the specified callback function.
840 865 */
841 866 int
842 867 ctf_type_visit(ctf_file_t *fp, ctf_id_t type, ctf_visit_f *func, void *arg)
843 868 {
844 869 return (ctf_type_rvisit(fp, type, func, arg, "", 0, 0));
845 870 }
↓ open down ↓ |
521 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX