1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Create and parse buffers containing CTF data. 28 */ 29 30 #include <sys/types.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 #include <ctype.h> 35 #include <zlib.h> 36 #include <elf.h> 37 38 #include "ctf_headers.h" 39 #include "ctftools.h" 40 #include "strtab.h" 41 #include "memory.h" 42 43 /* 44 * Name of the file currently being read, used to print error messages. We 45 * assume that only one file will be read at a time, and thus make no attempt 46 * to allow curfile to be used simultaneously by multiple threads. 47 * 48 * The value is only valid during a call to ctf_load. 49 */ 50 static char *curfile; 51 52 #define CTF_BUF_CHUNK_SIZE (64 * 1024) 53 #define RES_BUF_CHUNK_SIZE (64 * 1024) 54 55 struct ctf_buf { 56 strtab_t ctb_strtab; /* string table */ 57 caddr_t ctb_base; /* pointer to base of buffer */ 58 caddr_t ctb_end; /* pointer to end of buffer */ 59 caddr_t ctb_ptr; /* pointer to empty buffer space */ 60 size_t ctb_size; /* size of buffer */ 61 uint_t nptent; /* number of processed types */ 62 }; 63 64 /* 65 * Macros to reverse byte order 66 */ 67 #define BSWAP_8(x) ((x) & 0xff) 68 #define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8)) 69 #define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16)) 70 71 #define SWAP_16(x) (x) = BSWAP_16(x) 72 #define SWAP_32(x) (x) = BSWAP_32(x) 73 74 static int target_requires_swap; 75 76 /*PRINTFLIKE1*/ 77 static void 78 parseterminate(const char *fmt, ...) 79 { 80 static char msgbuf[1024]; /* sigh */ 81 va_list ap; 82 83 va_start(ap, fmt); 84 vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap); 85 va_end(ap); 86 87 terminate("%s: %s\n", curfile, msgbuf); 88 } 89 90 static void 91 ctf_buf_grow(ctf_buf_t *b) 92 { 93 off_t ptroff = b->ctb_ptr - b->ctb_base; 94 95 b->ctb_size += CTF_BUF_CHUNK_SIZE; 96 b->ctb_base = xrealloc(b->ctb_base, b->ctb_size); 97 b->ctb_end = b->ctb_base + b->ctb_size; 98 b->ctb_ptr = b->ctb_base + ptroff; 99 } 100 101 static ctf_buf_t * 102 ctf_buf_new(void) 103 { 104 ctf_buf_t *b = xcalloc(sizeof (ctf_buf_t)); 105 106 strtab_create(&b->ctb_strtab); 107 ctf_buf_grow(b); 108 109 return (b); 110 } 111 112 static void 113 ctf_buf_free(ctf_buf_t *b) 114 { 115 strtab_destroy(&b->ctb_strtab); 116 free(b->ctb_base); 117 free(b); 118 } 119 120 static uint_t 121 ctf_buf_cur(ctf_buf_t *b) 122 { 123 return (b->ctb_ptr - b->ctb_base); 124 } 125 126 static void 127 ctf_buf_write(ctf_buf_t *b, void const *p, size_t n) 128 { 129 size_t len; 130 131 while (n != 0) { 132 if (b->ctb_ptr == b->ctb_end) 133 ctf_buf_grow(b); 134 135 len = MIN((size_t)(b->ctb_end - b->ctb_ptr), n); 136 bcopy(p, b->ctb_ptr, len); 137 b->ctb_ptr += len; 138 139 p = (char const *)p + len; 140 n -= len; 141 } 142 } 143 144 static int 145 write_label(void *arg1, void *arg2) 146 { 147 labelent_t *le = arg1; 148 ctf_buf_t *b = arg2; 149 ctf_lblent_t ctl; 150 151 ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name); 152 ctl.ctl_typeidx = le->le_idx; 153 154 if (target_requires_swap) { 155 SWAP_32(ctl.ctl_label); 156 SWAP_32(ctl.ctl_typeidx); 157 } 158 159 ctf_buf_write(b, &ctl, sizeof (ctl)); 160 161 return (1); 162 } 163 164 static void 165 write_objects(iidesc_t *idp, ctf_buf_t *b) 166 { 167 uint_t id = (idp ? idp->ii_dtype->t_id : 0); 168 169 if (target_requires_swap) { 170 SWAP_32(id); 171 } 172 173 ctf_buf_write(b, &id, sizeof (id)); 174 175 debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); 176 } 177 178 static void 179 write_functions(iidesc_t *idp, ctf_buf_t *b) 180 { 181 uint_t fdata[2]; 182 uint_t id; 183 int nargs; 184 int i; 185 186 if (!idp) { 187 fdata[0] = 0; 188 ctf_buf_write(b, &fdata[0], sizeof (fdata[0])); 189 190 debug(3, "Wrote function (null)\n"); 191 return; 192 } 193 194 nargs = idp->ii_nargs + (idp->ii_vargs != 0); 195 196 if (nargs > CTF_V3_MAX_VLEN) { 197 terminate("function %s has too many args: %d > %d\n", 198 idp->ii_name, nargs, CTF_V3_MAX_VLEN); 199 } 200 201 fdata[0] = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); 202 fdata[1] = idp->ii_dtype->t_id; 203 204 if (target_requires_swap) { 205 SWAP_32(fdata[0]); 206 SWAP_32(fdata[1]); 207 } 208 209 ctf_buf_write(b, fdata, sizeof (fdata)); 210 211 for (i = 0; i < idp->ii_nargs; i++) { 212 id = idp->ii_args[i]->t_id; 213 214 if (target_requires_swap) { 215 SWAP_32(id); 216 } 217 218 ctf_buf_write(b, &id, sizeof (id)); 219 } 220 221 if (idp->ii_vargs) { 222 id = 0; 223 ctf_buf_write(b, &id, sizeof (id)); 224 } 225 226 debug(3, "Wrote function %s (%d args)\n", idp->ii_name, nargs); 227 } 228 229 /* 230 * Depending on the size of the type being described, either a ctf_stype_t (for 231 * types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be 232 * written. We isolate the determination here so the rest of the writer code 233 * doesn't need to care. 234 */ 235 static void 236 write_sized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt, size_t size) 237 { 238 if (size > CTF_V3_MAX_SIZE) { 239 ctt->ctt_size = CTF_V3_LSIZE_SENT; 240 ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); 241 ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); 242 if (target_requires_swap) { 243 SWAP_32(ctt->ctt_name); 244 SWAP_32(ctt->ctt_info); 245 SWAP_32(ctt->ctt_size); 246 SWAP_32(ctt->ctt_lsizehi); 247 SWAP_32(ctt->ctt_lsizelo); 248 } 249 ctf_buf_write(b, ctt, sizeof (*ctt)); 250 } else { 251 struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; 252 253 cts->ctt_size = size; 254 255 if (target_requires_swap) { 256 SWAP_32(cts->ctt_name); 257 SWAP_32(cts->ctt_info); 258 SWAP_32(cts->ctt_size); 259 } 260 261 ctf_buf_write(b, cts, sizeof (*cts)); 262 } 263 } 264 265 static void 266 write_unsized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt) 267 { 268 struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; 269 270 if (target_requires_swap) { 271 SWAP_32(cts->ctt_name); 272 SWAP_32(cts->ctt_info); 273 SWAP_32(cts->ctt_size); 274 } 275 276 ctf_buf_write(b, cts, sizeof (*cts)); 277 } 278 279 static int 280 write_type(void *arg1, void *arg2) 281 { 282 tdesc_t *tp = arg1; 283 ctf_buf_t *b = arg2; 284 elist_t *ep; 285 mlist_t *mp; 286 intr_t *ip; 287 288 size_t offset; 289 uint_t encoding; 290 uint_t data; 291 int isroot = tp->t_flags & TDESC_F_ISROOT; 292 int i; 293 294 struct ctf_type_v3 ctt; 295 struct ctf_array_v3 cta; 296 struct ctf_member_v3 ctm; 297 struct ctf_lmember_v3 ctlm; 298 struct ctf_enum cte; 299 uint_t id; 300 301 /* 302 * There shouldn't be any holes in the type list (where a hole is 303 * defined as two consecutive tdescs without consecutive ids), but 304 * check for them just in case. If we do find holes, we need to make 305 * fake entries to fill the holes, or we won't be able to reconstruct 306 * the tree from the written data. 307 */ 308 if (++b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { 309 debug(2, "genctf: type hole from %d < x < %d\n", 310 b->nptent - 1, CTF_V3_TYPE_TO_INDEX(tp->t_id)); 311 312 ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, 0); 313 ctt.ctt_info = CTF_V3_TYPE_INFO(0, 0, 0); 314 while (b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { 315 write_sized_type_rec(b, &ctt, 0); 316 b->nptent++; 317 } 318 } 319 320 offset = strtab_insert(&b->ctb_strtab, tp->t_name); 321 ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); 322 323 switch (tp->t_type) { 324 case INTRINSIC: 325 ip = tp->t_intr; 326 if (ip->intr_type == INTR_INT) 327 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_INTEGER, 328 isroot, 1); 329 else 330 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FLOAT, isroot, 1); 331 write_sized_type_rec(b, &ctt, tp->t_size); 332 333 encoding = 0; 334 335 if (ip->intr_type == INTR_INT) { 336 if (ip->intr_signed) 337 encoding |= CTF_INT_SIGNED; 338 if (ip->intr_iformat == 'c') 339 encoding |= CTF_INT_CHAR; 340 else if (ip->intr_iformat == 'b') 341 encoding |= CTF_INT_BOOL; 342 else if (ip->intr_iformat == 'v') 343 encoding |= CTF_INT_VARARGS; 344 } else 345 encoding = ip->intr_fformat; 346 347 data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits); 348 if (target_requires_swap) { 349 SWAP_32(data); 350 } 351 ctf_buf_write(b, &data, sizeof (data)); 352 break; 353 354 case POINTER: 355 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_POINTER, isroot, 0); 356 ctt.ctt_type = tp->t_tdesc->t_id; 357 write_unsized_type_rec(b, &ctt); 358 break; 359 360 case ARRAY: 361 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ARRAY, isroot, 1); 362 write_sized_type_rec(b, &ctt, tp->t_size); 363 364 cta.cta_contents = tp->t_ardef->ad_contents->t_id; 365 cta.cta_index = tp->t_ardef->ad_idxtype->t_id; 366 cta.cta_nelems = tp->t_ardef->ad_nelems; 367 if (target_requires_swap) { 368 SWAP_32(cta.cta_contents); 369 SWAP_32(cta.cta_index); 370 SWAP_32(cta.cta_nelems); 371 } 372 ctf_buf_write(b, &cta, sizeof (cta)); 373 break; 374 375 case STRUCT: 376 case UNION: 377 for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) 378 i++; /* count up struct or union members */ 379 380 if (i > CTF_V3_MAX_VLEN) { 381 terminate("sou %s has too many members: %d > %d\n", 382 tdesc_name(tp), i, CTF_V3_MAX_VLEN); 383 } 384 385 if (tp->t_type == STRUCT) 386 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_STRUCT, isroot, i); 387 else 388 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_UNION, isroot, i); 389 390 write_sized_type_rec(b, &ctt, tp->t_size); 391 392 if (tp->t_size < CTF_V3_LSTRUCT_THRESH) { 393 for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { 394 offset = strtab_insert(&b->ctb_strtab, 395 mp->ml_name); 396 397 ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 398 offset); 399 ctm.ctm_type = mp->ml_type->t_id; 400 ctm.ctm_offset = mp->ml_offset; 401 if (target_requires_swap) { 402 SWAP_32(ctm.ctm_name); 403 SWAP_32(ctm.ctm_type); 404 SWAP_32(ctm.ctm_offset); 405 } 406 ctf_buf_write(b, &ctm, sizeof (ctm)); 407 } 408 } else { 409 for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { 410 offset = strtab_insert(&b->ctb_strtab, 411 mp->ml_name); 412 413 ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 414 offset); 415 ctlm.ctlm_type = mp->ml_type->t_id; 416 ctlm.ctlm_offsethi = 417 CTF_OFFSET_TO_LMEMHI(mp->ml_offset); 418 ctlm.ctlm_offsetlo = 419 CTF_OFFSET_TO_LMEMLO(mp->ml_offset); 420 421 if (target_requires_swap) { 422 SWAP_32(ctlm.ctlm_name); 423 SWAP_32(ctlm.ctlm_type); 424 SWAP_32(ctlm.ctlm_offsethi); 425 SWAP_32(ctlm.ctlm_offsetlo); 426 } 427 428 ctf_buf_write(b, &ctlm, sizeof (ctlm)); 429 } 430 } 431 break; 432 433 case ENUM: 434 for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next) 435 i++; /* count up enum members */ 436 437 if (i > CTF_V3_MAX_VLEN) { 438 i = CTF_V3_MAX_VLEN; 439 } 440 441 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ENUM, isroot, i); 442 write_sized_type_rec(b, &ctt, tp->t_size); 443 444 for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) { 445 offset = strtab_insert(&b->ctb_strtab, ep->el_name); 446 cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); 447 cte.cte_value = ep->el_number; 448 449 if (target_requires_swap) { 450 SWAP_32(cte.cte_name); 451 SWAP_32(cte.cte_value); 452 } 453 454 ctf_buf_write(b, &cte, sizeof (cte)); 455 i--; 456 } 457 break; 458 459 case FORWARD: 460 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FORWARD, isroot, 0); 461 ctt.ctt_type = 0; 462 write_unsized_type_rec(b, &ctt); 463 break; 464 465 case TYPEDEF: 466 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0); 467 ctt.ctt_type = tp->t_tdesc->t_id; 468 write_unsized_type_rec(b, &ctt); 469 break; 470 471 case VOLATILE: 472 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_VOLATILE, isroot, 0); 473 ctt.ctt_type = tp->t_tdesc->t_id; 474 write_unsized_type_rec(b, &ctt); 475 break; 476 477 case CONST: 478 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_CONST, isroot, 0); 479 ctt.ctt_type = tp->t_tdesc->t_id; 480 write_unsized_type_rec(b, &ctt); 481 break; 482 483 case FUNCTION: 484 i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs; 485 486 if (i > CTF_V3_MAX_VLEN) { 487 terminate("function %s has too many args: %d > %d\n", 488 tdesc_name(tp), i, CTF_V3_MAX_VLEN); 489 } 490 491 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, isroot, i); 492 ctt.ctt_type = tp->t_fndef->fn_ret->t_id; 493 write_unsized_type_rec(b, &ctt); 494 495 for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) { 496 id = tp->t_fndef->fn_args[i]->t_id; 497 498 if (target_requires_swap) { 499 SWAP_32(id); 500 } 501 502 ctf_buf_write(b, &id, sizeof (id)); 503 } 504 505 if (tp->t_fndef->fn_vargs) { 506 id = 0; 507 ctf_buf_write(b, &id, sizeof (id)); 508 i++; 509 } 510 511 break; 512 513 case RESTRICT: 514 ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_RESTRICT, isroot, 0); 515 ctt.ctt_type = tp->t_tdesc->t_id; 516 write_unsized_type_rec(b, &ctt); 517 break; 518 519 default: 520 warning("Can't write unknown type %d\n", tp->t_type); 521 } 522 523 debug(3, "Wrote type %d %s\n", tp->t_id, tdesc_name(tp)); 524 525 return (1); 526 } 527 528 typedef struct resbuf { 529 caddr_t rb_base; 530 caddr_t rb_ptr; 531 size_t rb_size; 532 z_stream rb_zstr; 533 } resbuf_t; 534 535 static void 536 rbzs_grow(resbuf_t *rb) 537 { 538 off_t ptroff = (caddr_t)rb->rb_zstr.next_out - rb->rb_base; 539 540 rb->rb_size += RES_BUF_CHUNK_SIZE; 541 rb->rb_base = xrealloc(rb->rb_base, rb->rb_size); 542 rb->rb_ptr = rb->rb_base + ptroff; 543 rb->rb_zstr.next_out = (Bytef *)(rb->rb_ptr); 544 rb->rb_zstr.avail_out += RES_BUF_CHUNK_SIZE; 545 } 546 547 static void 548 compress_start(resbuf_t *rb) 549 { 550 int rc; 551 552 rb->rb_zstr.zalloc = (alloc_func)0; 553 rb->rb_zstr.zfree = (free_func)0; 554 rb->rb_zstr.opaque = (voidpf)0; 555 556 if ((rc = deflateInit(&rb->rb_zstr, Z_BEST_COMPRESSION)) != Z_OK) 557 parseterminate("zlib start failed: %s", zError(rc)); 558 } 559 560 static ssize_t 561 compress_buffer(void *buf, size_t n, void *data) 562 { 563 resbuf_t *rb = (resbuf_t *)data; 564 int rc; 565 566 rb->rb_zstr.next_out = (Bytef *)rb->rb_ptr; 567 rb->rb_zstr.avail_out = rb->rb_size - (rb->rb_ptr - rb->rb_base); 568 rb->rb_zstr.next_in = buf; 569 rb->rb_zstr.avail_in = n; 570 571 while (rb->rb_zstr.avail_in) { 572 if (rb->rb_zstr.avail_out == 0) 573 rbzs_grow(rb); 574 575 if ((rc = deflate(&rb->rb_zstr, Z_NO_FLUSH)) != Z_OK) 576 parseterminate("zlib deflate failed: %s", zError(rc)); 577 } 578 rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 579 580 return (n); 581 } 582 583 static void 584 compress_flush(resbuf_t *rb, int type) 585 { 586 int rc; 587 588 for (;;) { 589 if (rb->rb_zstr.avail_out == 0) 590 rbzs_grow(rb); 591 592 rc = deflate(&rb->rb_zstr, type); 593 if ((type == Z_FULL_FLUSH && rc == Z_BUF_ERROR) || 594 (type == Z_FINISH && rc == Z_STREAM_END)) 595 break; 596 else if (rc != Z_OK) 597 parseterminate("zlib finish failed: %s", zError(rc)); 598 } 599 rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 600 } 601 602 static void 603 compress_end(resbuf_t *rb) 604 { 605 int rc; 606 607 compress_flush(rb, Z_FINISH); 608 609 if ((rc = deflateEnd(&rb->rb_zstr)) != Z_OK) 610 parseterminate("zlib end failed: %s", zError(rc)); 611 } 612 613 /* 614 * Pad the buffer to a power-of-2 boundary 615 */ 616 static void 617 pad_buffer(ctf_buf_t *buf, int align) 618 { 619 uint_t cur = ctf_buf_cur(buf); 620 ssize_t topad = (align - (cur % align)) % align; 621 static const char pad[8] = { 0 }; 622 623 while (topad > 0) { 624 ctf_buf_write(buf, pad, (topad > 8 ? 8 : topad)); 625 topad -= 8; 626 } 627 } 628 629 static ssize_t 630 bcopy_data(void *buf, size_t n, void *data) 631 { 632 caddr_t *posp = (caddr_t *)data; 633 bcopy(buf, *posp, n); 634 *posp += n; 635 return (n); 636 } 637 638 static caddr_t 639 write_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 640 { 641 caddr_t outbuf; 642 caddr_t bufpos; 643 644 outbuf = xmalloc(sizeof (ctf_header_t) + (buf->ctb_ptr - buf->ctb_base) 645 + buf->ctb_strtab.str_size); 646 647 bufpos = outbuf; 648 (void) bcopy_data(h, sizeof (ctf_header_t), &bufpos); 649 (void) bcopy_data(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 650 &bufpos); 651 (void) strtab_write(&buf->ctb_strtab, bcopy_data, &bufpos); 652 *resszp = bufpos - outbuf; 653 return (outbuf); 654 } 655 656 /* 657 * Create the compression buffer, and fill it with the CTF and string 658 * table data. We flush the compression state between the two so the 659 * dictionary used for the string tables won't be polluted with values 660 * that made sense for the CTF data. 661 */ 662 static caddr_t 663 write_compressed_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 664 { 665 resbuf_t resbuf; 666 resbuf.rb_size = RES_BUF_CHUNK_SIZE; 667 resbuf.rb_base = xmalloc(resbuf.rb_size); 668 bcopy(h, resbuf.rb_base, sizeof (ctf_header_t)); 669 resbuf.rb_ptr = resbuf.rb_base + sizeof (ctf_header_t); 670 671 compress_start(&resbuf); 672 (void) compress_buffer(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 673 &resbuf); 674 compress_flush(&resbuf, Z_FULL_FLUSH); 675 (void) strtab_write(&buf->ctb_strtab, compress_buffer, &resbuf); 676 compress_end(&resbuf); 677 678 *resszp = (resbuf.rb_ptr - resbuf.rb_base); 679 return (resbuf.rb_base); 680 } 681 682 caddr_t 683 ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) 684 { 685 ctf_buf_t *buf = ctf_buf_new(); 686 ctf_header_t h; 687 caddr_t outbuf; 688 689 int i; 690 691 target_requires_swap = do_compress & CTF_SWAP_BYTES; 692 do_compress &= ~CTF_SWAP_BYTES; 693 694 /* 695 * Prepare the header, and create the CTF output buffers. The data 696 * object section and function section are both lists of 2-byte 697 * integers; we pad these out to the next 4-byte boundary if needed. 698 */ 699 h.cth_magic = CTF_MAGIC; 700 h.cth_version = CTF_VERSION_3; 701 h.cth_flags = do_compress ? CTF_F_COMPRESS : 0; 702 h.cth_parlabel = strtab_insert(&buf->ctb_strtab, 703 iiburst->iib_td->td_parlabel); 704 h.cth_parname = strtab_insert(&buf->ctb_strtab, 705 iiburst->iib_td->td_parname); 706 707 h.cth_lbloff = 0; 708 (void) list_iter(iiburst->iib_td->td_labels, write_label, 709 buf); 710 711 pad_buffer(buf, 2); 712 h.cth_objtoff = ctf_buf_cur(buf); 713 for (i = 0; i < iiburst->iib_nobjts; i++) 714 write_objects(iiburst->iib_objts[i], buf); 715 716 pad_buffer(buf, 2); 717 h.cth_funcoff = ctf_buf_cur(buf); 718 for (i = 0; i < iiburst->iib_nfuncs; i++) 719 write_functions(iiburst->iib_funcs[i], buf); 720 721 pad_buffer(buf, 4); 722 h.cth_typeoff = ctf_buf_cur(buf); 723 (void) list_iter(iiburst->iib_types, write_type, buf); 724 725 debug(2, "CTF wrote %d types\n", list_count(iiburst->iib_types)); 726 727 h.cth_stroff = ctf_buf_cur(buf); 728 h.cth_strlen = strtab_size(&buf->ctb_strtab); 729 730 if (target_requires_swap) { 731 SWAP_16(h.cth_preamble.ctp_magic); 732 SWAP_32(h.cth_parlabel); 733 SWAP_32(h.cth_parname); 734 SWAP_32(h.cth_lbloff); 735 SWAP_32(h.cth_objtoff); 736 SWAP_32(h.cth_funcoff); 737 SWAP_32(h.cth_typeoff); 738 SWAP_32(h.cth_stroff); 739 SWAP_32(h.cth_strlen); 740 } 741 742 /* 743 * We only do compression for ctfmerge, as ctfconvert is only 744 * supposed to be used on intermediary build objects. This is 745 * significantly faster. 746 */ 747 if (do_compress) 748 outbuf = write_compressed_buffer(&h, buf, resszp); 749 else 750 outbuf = write_buffer(&h, buf, resszp); 751 752 ctf_buf_free(buf); 753 return (outbuf); 754 } 755 756 static void 757 get_ctt_info(ctf_header_t *h, void *v, uint_t *kind, uint_t *vlen, int *isroot) 758 { 759 if (h->cth_version == CTF_VERSION_2) { 760 struct ctf_type_v2 *ctt = v; 761 762 *kind = CTF_V2_INFO_KIND(ctt->ctt_info); 763 *vlen = CTF_V2_INFO_VLEN(ctt->ctt_info); 764 *isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info); 765 } else { 766 struct ctf_type_v3 *ctt = v; 767 768 *kind = CTF_V3_INFO_KIND(ctt->ctt_info); 769 *vlen = CTF_V3_INFO_VLEN(ctt->ctt_info); 770 *isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info); 771 } 772 } 773 774 static void 775 get_ctt_size(ctf_header_t *h, void *v, size_t *sizep, size_t *incrementp) 776 { 777 if (h->cth_version == CTF_VERSION_2) { 778 struct ctf_type_v2 *ctt = v; 779 780 if (ctt->ctt_size == CTF_V2_LSIZE_SENT) { 781 *sizep = (size_t)CTF_TYPE_LSIZE(ctt); 782 *incrementp = sizeof (struct ctf_type_v2); 783 } else { 784 *sizep = ctt->ctt_size; 785 *incrementp = sizeof (struct ctf_stype_v2); 786 } 787 } else { 788 struct ctf_type_v3 *ctt = v; 789 790 if (ctt->ctt_size == CTF_V3_LSIZE_SENT) { 791 *sizep = (size_t)CTF_TYPE_LSIZE(ctt); 792 *incrementp = sizeof (struct ctf_type_v3); 793 } else { 794 *sizep = ctt->ctt_size; 795 *incrementp = sizeof (struct ctf_stype_v3); 796 } 797 } 798 } 799 800 static int 801 count_types(ctf_header_t *h, caddr_t data) 802 { 803 caddr_t dptr = data + h->cth_typeoff; 804 uint_t version = h->cth_version; 805 size_t idwidth; 806 int count = 0; 807 808 idwidth = version == CTF_VERSION_2 ? 2 : 4; 809 dptr = data + h->cth_typeoff; 810 while (dptr < data + h->cth_stroff) { 811 void *v = (void *) dptr; 812 size_t size, increment; 813 uint_t vlen, kind; 814 int isroot; 815 816 get_ctt_info(h, v, &kind, &vlen, &isroot); 817 get_ctt_size(h, v, &size, &increment); 818 819 switch (kind) { 820 case CTF_K_INTEGER: 821 case CTF_K_FLOAT: 822 dptr += 4; 823 break; 824 case CTF_K_POINTER: 825 case CTF_K_FORWARD: 826 case CTF_K_TYPEDEF: 827 case CTF_K_VOLATILE: 828 case CTF_K_CONST: 829 case CTF_K_RESTRICT: 830 case CTF_K_FUNCTION: 831 dptr += idwidth * vlen; 832 break; 833 case CTF_K_ARRAY: 834 if (version == CTF_VERSION_2) 835 dptr += sizeof (struct ctf_array_v2); 836 else 837 dptr += sizeof (struct ctf_array_v3); 838 break; 839 case CTF_K_STRUCT: 840 case CTF_K_UNION: 841 if (version == CTF_VERSION_2) { 842 if (size < CTF_V2_LSTRUCT_THRESH) 843 dptr += sizeof (struct ctf_member_v2) * 844 vlen; 845 else 846 dptr += sizeof (struct ctf_lmember_v2) * 847 vlen; 848 } else { 849 if (size < CTF_V3_LSTRUCT_THRESH) 850 dptr += sizeof (struct ctf_member_v3) * 851 vlen; 852 else 853 dptr += sizeof (struct ctf_lmember_v3) * 854 vlen; 855 } 856 break; 857 case CTF_K_ENUM: 858 dptr += sizeof (ctf_enum_t) * vlen; 859 break; 860 case CTF_K_UNKNOWN: 861 break; 862 default: 863 parseterminate("Unknown CTF type %d (#%d) at %#x", 864 kind, count, dptr - data); 865 } 866 867 dptr += increment; 868 count++; 869 } 870 871 debug(3, "CTF read %d types\n", count); 872 873 return (count); 874 } 875 876 /* 877 * Resurrect the labels stored in the CTF data, returning the index associated 878 * with a label provided by the caller. There are several cases, outlined 879 * below. Note that, given two labels, the one associated with the lesser type 880 * index is considered to be older than the other. 881 * 882 * 1. matchlbl == NULL - return the index of the most recent label. 883 * 2. matchlbl == "BASE" - return the index of the oldest label. 884 * 3. matchlbl != NULL, but doesn't match any labels in the section - warn 885 * the user, and proceed as if matchlbl == "BASE" (for safety). 886 * 4. matchlbl != NULL, and matches one of the labels in the section - return 887 * the type index associated with the label. 888 */ 889 static int 890 resurrect_labels(ctf_header_t *h, tdata_t *td, caddr_t ctfdata, char *matchlbl) 891 { 892 caddr_t buf = ctfdata + h->cth_lbloff; 893 caddr_t sbuf = ctfdata + h->cth_stroff; 894 size_t bufsz = h->cth_objtoff - h->cth_lbloff; 895 int lastidx = 0, baseidx = -1; 896 char *baselabel = NULL; 897 ctf_lblent_t *ctl; 898 void *v = (void *) buf; 899 900 for (ctl = v; (caddr_t)ctl < buf + bufsz; ctl++) { 901 char *label = sbuf + ctl->ctl_label; 902 903 lastidx = ctl->ctl_typeidx; 904 905 debug(3, "Resurrected label %s type idx %d\n", label, lastidx); 906 907 tdata_label_add(td, label, lastidx); 908 909 if (baseidx == -1) { 910 baseidx = lastidx; 911 baselabel = label; 912 if (matchlbl != NULL && streq(matchlbl, "BASE")) 913 return (lastidx); 914 } 915 916 if (matchlbl != NULL && streq(label, matchlbl)) 917 return (lastidx); 918 } 919 920 if (matchlbl != NULL) { 921 /* User provided a label that didn't match */ 922 warning("%s: Cannot find label `%s' - using base (%s)\n", 923 curfile, matchlbl, (baselabel ? baselabel : "NONE")); 924 925 tdata_label_free(td); 926 tdata_label_add(td, baselabel, baseidx); 927 928 return (baseidx); 929 } 930 931 return (lastidx); 932 } 933 934 static void 935 resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 936 caddr_t ctfdata, symit_data_t *si) 937 { 938 caddr_t buf = ctfdata + h->cth_objtoff; 939 size_t bufsz = h->cth_funcoff - h->cth_objtoff; 940 caddr_t dptr; 941 size_t idwidth; 942 943 idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; 944 945 symit_reset(si); 946 for (dptr = buf; dptr < buf + bufsz; dptr += idwidth) { 947 uint32_t id = 0; 948 949 memcpy(&id, (void *) dptr, idwidth); 950 iidesc_t *ii; 951 GElf_Sym *sym; 952 953 if (!(sym = symit_next(si, STT_OBJECT)) && id != 0) { 954 parseterminate( 955 "Unexpected end of object symbols at %x of %x", 956 dptr - buf, bufsz); 957 } 958 959 if (id == 0) { 960 debug(3, "Skipping null object\n"); 961 continue; 962 } else if (id >= (uint_t)tdsize) { 963 parseterminate("Reference to invalid type %d", id); 964 } 965 966 ii = iidesc_new(symit_name(si)); 967 ii->ii_dtype = tdarr[id]; 968 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 969 ii->ii_type = II_SVAR; 970 ii->ii_owner = xstrdup(symit_curfile(si)); 971 } else 972 ii->ii_type = II_GVAR; 973 hash_add(td->td_iihash, ii); 974 975 debug(3, "Resurrected %s object %s (%d) from %s\n", 976 (ii->ii_type == II_GVAR ? "global" : "static"), 977 ii->ii_name, id, (ii->ii_owner ? ii->ii_owner : "(none)")); 978 } 979 } 980 981 static void 982 resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 983 caddr_t ctfdata, symit_data_t *si) 984 { 985 caddr_t buf = ctfdata + h->cth_funcoff; 986 size_t bufsz = h->cth_typeoff - h->cth_funcoff; 987 size_t idwidth; 988 caddr_t dptr = buf; 989 iidesc_t *ii; 990 GElf_Sym *sym; 991 int i; 992 993 idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; 994 995 symit_reset(si); 996 while (dptr < buf + bufsz) { 997 uint32_t id, info, retid; 998 999 info = 0; 1000 memcpy(&info, (void *) dptr, idwidth); 1001 dptr += idwidth; 1002 1003 if (!(sym = symit_next(si, STT_FUNC)) && info != 0) 1004 parseterminate("Unexpected end of function symbols"); 1005 1006 if (info == 0) { 1007 debug(3, "Skipping null function (%s)\n", 1008 symit_name(si)); 1009 continue; 1010 } 1011 1012 retid = 0; 1013 memcpy(&retid, (void *) dptr, idwidth); 1014 dptr += idwidth; 1015 1016 if (retid >= (uint_t)tdsize) 1017 parseterminate("Reference to invalid type %d", retid); 1018 1019 ii = iidesc_new(symit_name(si)); 1020 ii->ii_dtype = tdarr[retid]; 1021 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 1022 ii->ii_type = II_SFUN; 1023 ii->ii_owner = xstrdup(symit_curfile(si)); 1024 } else 1025 ii->ii_type = II_GFUN; 1026 if (h->cth_version == CTF_VERSION_2) 1027 ii->ii_nargs = CTF_V2_INFO_VLEN(info); 1028 else 1029 ii->ii_nargs = CTF_V3_INFO_VLEN(info); 1030 if (ii->ii_nargs) 1031 ii->ii_args = 1032 xmalloc(sizeof (tdesc_t *) * ii->ii_nargs); 1033 1034 for (i = 0; i < ii->ii_nargs; i++, dptr += idwidth) { 1035 id = 0; 1036 memcpy(&id, (void *) dptr, idwidth); 1037 if (id >= (uint_t)tdsize) 1038 parseterminate("Reference to invalid type %d", 1039 id); 1040 ii->ii_args[i] = tdarr[id]; 1041 } 1042 1043 if (ii->ii_nargs && ii->ii_args[ii->ii_nargs - 1] == NULL) { 1044 ii->ii_nargs--; 1045 ii->ii_vargs = 1; 1046 } 1047 1048 hash_add(td->td_iihash, ii); 1049 1050 debug(3, "Resurrected %s function %s (%d, %d args)\n", 1051 (ii->ii_type == II_GFUN ? "global" : "static"), 1052 ii->ii_name, retid, ii->ii_nargs); 1053 } 1054 } 1055 1056 static void 1057 resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 1058 caddr_t ctfdata, int maxid) 1059 { 1060 caddr_t buf = ctfdata + h->cth_typeoff; 1061 size_t bufsz = h->cth_stroff - h->cth_typeoff; 1062 caddr_t sbuf = ctfdata + h->cth_stroff; 1063 caddr_t dptr = buf; 1064 tdesc_t *tdp; 1065 uint_t data; 1066 uint_t encoding; 1067 size_t idwidth, size, increment; 1068 int tcnt; 1069 int iicnt = 0; 1070 tid_t tid, argid; 1071 int isroot, kind, vlen; 1072 int i, version; 1073 1074 elist_t **epp; 1075 mlist_t **mpp; 1076 intr_t *ip; 1077 1078 version = h->cth_version; 1079 idwidth = version == CTF_VERSION_2 ? 2 : 4; 1080 1081 /* 1082 * A maxid of zero indicates a request to resurrect all types, so reset 1083 * maxid to the maximum type id. 1084 */ 1085 if (maxid == 0) { 1086 maxid = version == CTF_VERSION_2 ? 1087 CTF_V2_MAX_TYPE : CTF_V3_MAX_TYPE; 1088 } 1089 1090 for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) { 1091 ctf_enum_t *cte; 1092 uint_t name, type; 1093 void *v; 1094 1095 if (tid > maxid) 1096 break; 1097 1098 if (tid >= tdsize) 1099 parseterminate("Reference to invalid type %d", tid); 1100 1101 get_ctt_info(h, dptr, &kind, &vlen, &isroot); 1102 get_ctt_size(h, dptr, &size, &increment); 1103 if (version == CTF_VERSION_2) { 1104 struct ctf_type_v2 *ctt = (void *) dptr; 1105 1106 name = ctt->ctt_name; 1107 type = ctt->ctt_type; 1108 } else { 1109 struct ctf_type_v3 *ctt = (void *) dptr; 1110 1111 name = ctt->ctt_name; 1112 type = ctt->ctt_type; 1113 } 1114 dptr += increment; 1115 1116 tdp = tdarr[tid]; 1117 1118 if (CTF_NAME_STID(name) != CTF_STRTAB_0) 1119 parseterminate( 1120 "Unable to cope with non-zero strtab id"); 1121 if (CTF_NAME_OFFSET(name) != 0) { 1122 tdp->t_name = xstrdup(sbuf + CTF_NAME_OFFSET(name)); 1123 } else 1124 tdp->t_name = NULL; 1125 1126 switch (kind) { 1127 case CTF_K_INTEGER: 1128 tdp->t_type = INTRINSIC; 1129 tdp->t_size = size; 1130 1131 v = (void *) dptr; 1132 data = *((uint_t *)v); 1133 dptr += sizeof (uint_t); 1134 encoding = CTF_INT_ENCODING(data); 1135 1136 ip = xmalloc(sizeof (intr_t)); 1137 ip->intr_type = INTR_INT; 1138 ip->intr_signed = (encoding & CTF_INT_SIGNED) ? 1 : 0; 1139 1140 if (encoding & CTF_INT_CHAR) 1141 ip->intr_iformat = 'c'; 1142 else if (encoding & CTF_INT_BOOL) 1143 ip->intr_iformat = 'b'; 1144 else if (encoding & CTF_INT_VARARGS) 1145 ip->intr_iformat = 'v'; 1146 else 1147 ip->intr_iformat = '\0'; 1148 1149 ip->intr_offset = CTF_INT_OFFSET(data); 1150 ip->intr_nbits = CTF_INT_BITS(data); 1151 tdp->t_intr = ip; 1152 break; 1153 1154 case CTF_K_FLOAT: 1155 tdp->t_type = INTRINSIC; 1156 tdp->t_size = size; 1157 1158 v = (void *) dptr; 1159 data = *((uint_t *)v); 1160 dptr += sizeof (uint_t); 1161 1162 ip = xcalloc(sizeof (intr_t)); 1163 ip->intr_type = INTR_REAL; 1164 ip->intr_fformat = CTF_FP_ENCODING(data); 1165 ip->intr_offset = CTF_FP_OFFSET(data); 1166 ip->intr_nbits = CTF_FP_BITS(data); 1167 tdp->t_intr = ip; 1168 break; 1169 1170 case CTF_K_POINTER: 1171 tdp->t_type = POINTER; 1172 tdp->t_tdesc = tdarr[type]; 1173 break; 1174 1175 case CTF_K_ARRAY: { 1176 uint_t contents, index, nelems; 1177 1178 tdp->t_type = ARRAY; 1179 tdp->t_size = size; 1180 1181 if (version == CTF_VERSION_2) { 1182 struct ctf_array_v2 *cta = (void *) dptr; 1183 contents = cta->cta_contents; 1184 index = cta->cta_index; 1185 nelems = cta->cta_nelems; 1186 dptr += sizeof (*cta); 1187 } else { 1188 struct ctf_array_v3 *cta = (void *) dptr; 1189 contents = cta->cta_contents; 1190 index = cta->cta_index; 1191 nelems = cta->cta_nelems; 1192 dptr += sizeof (*cta); 1193 } 1194 1195 tdp->t_ardef = xmalloc(sizeof (ardef_t)); 1196 tdp->t_ardef->ad_contents = tdarr[contents]; 1197 tdp->t_ardef->ad_idxtype = tdarr[index]; 1198 tdp->t_ardef->ad_nelems = nelems; 1199 break; 1200 } 1201 1202 case CTF_K_STRUCT: 1203 case CTF_K_UNION: { 1204 tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION); 1205 tdp->t_size = size; 1206 1207 if (version == CTF_VERSION_2) { 1208 if (size < CTF_V2_LSTRUCT_THRESH) { 1209 for (i = 0, mpp = &tdp->t_members; i < vlen; 1210 i++, mpp = &((*mpp)->ml_next)) { 1211 v = (void *) dptr; 1212 struct ctf_member_v2 *ctm = v; 1213 dptr += sizeof (struct ctf_member_v2); 1214 1215 *mpp = xmalloc(sizeof (mlist_t)); 1216 (*mpp)->ml_name = xstrdup(sbuf + 1217 ctm->ctm_name); 1218 (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1219 (*mpp)->ml_offset = ctm->ctm_offset; 1220 (*mpp)->ml_size = 0; 1221 } 1222 } else { 1223 for (i = 0, mpp = &tdp->t_members; i < vlen; 1224 i++, mpp = &((*mpp)->ml_next)) { 1225 v = (void *) dptr; 1226 struct ctf_lmember_v2 *ctlm = v; 1227 dptr += sizeof (struct ctf_lmember_v2); 1228 1229 *mpp = xmalloc(sizeof (mlist_t)); 1230 (*mpp)->ml_name = xstrdup(sbuf + 1231 ctlm->ctlm_name); 1232 (*mpp)->ml_type = 1233 tdarr[ctlm->ctlm_type]; 1234 (*mpp)->ml_offset = 1235 (int)CTF_LMEM_OFFSET(ctlm); 1236 (*mpp)->ml_size = 0; 1237 } 1238 } 1239 } else { 1240 if (size < CTF_V3_LSTRUCT_THRESH) { 1241 for (i = 0, mpp = &tdp->t_members; i < vlen; 1242 i++, mpp = &((*mpp)->ml_next)) { 1243 v = (void *) dptr; 1244 struct ctf_member_v3 *ctm = v; 1245 dptr += sizeof (struct ctf_member_v3); 1246 1247 *mpp = xmalloc(sizeof (mlist_t)); 1248 (*mpp)->ml_name = xstrdup(sbuf + 1249 ctm->ctm_name); 1250 (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1251 (*mpp)->ml_offset = ctm->ctm_offset; 1252 (*mpp)->ml_size = 0; 1253 } 1254 } else { 1255 for (i = 0, mpp = &tdp->t_members; i < vlen; 1256 i++, mpp = &((*mpp)->ml_next)) { 1257 v = (void *) dptr; 1258 struct ctf_lmember_v3 *ctlm = v; 1259 dptr += sizeof (struct ctf_lmember_v3); 1260 1261 *mpp = xmalloc(sizeof (mlist_t)); 1262 (*mpp)->ml_name = xstrdup(sbuf + 1263 ctlm->ctlm_name); 1264 (*mpp)->ml_type = 1265 tdarr[ctlm->ctlm_type]; 1266 (*mpp)->ml_offset = 1267 (int)CTF_LMEM_OFFSET(ctlm); 1268 (*mpp)->ml_size = 0; 1269 } 1270 } 1271 } 1272 1273 *mpp = NULL; 1274 break; 1275 } 1276 1277 case CTF_K_ENUM: 1278 tdp->t_type = ENUM; 1279 tdp->t_size = size; 1280 1281 for (i = 0, epp = &tdp->t_emem; i < vlen; 1282 i++, epp = &((*epp)->el_next)) { 1283 v = (void *) dptr; 1284 cte = v; 1285 dptr += sizeof (ctf_enum_t); 1286 1287 *epp = xmalloc(sizeof (elist_t)); 1288 (*epp)->el_name = xstrdup(sbuf + cte->cte_name); 1289 (*epp)->el_number = cte->cte_value; 1290 } 1291 *epp = NULL; 1292 break; 1293 1294 case CTF_K_FORWARD: 1295 tdp->t_type = FORWARD; 1296 list_add(&td->td_fwdlist, tdp); 1297 break; 1298 1299 case CTF_K_TYPEDEF: 1300 tdp->t_type = TYPEDEF; 1301 tdp->t_tdesc = tdarr[type]; 1302 break; 1303 1304 case CTF_K_VOLATILE: 1305 tdp->t_type = VOLATILE; 1306 tdp->t_tdesc = tdarr[type]; 1307 break; 1308 1309 case CTF_K_CONST: 1310 tdp->t_type = CONST; 1311 tdp->t_tdesc = tdarr[type]; 1312 break; 1313 1314 case CTF_K_FUNCTION: 1315 tdp->t_type = FUNCTION; 1316 tdp->t_fndef = xcalloc(sizeof (fndef_t)); 1317 tdp->t_fndef->fn_ret = tdarr[type]; 1318 1319 v = (void *) (dptr + (idwidth * (vlen - 1))); 1320 if (vlen > 0 && *(uint_t *)v == 0) 1321 tdp->t_fndef->fn_vargs = 1; 1322 1323 tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs; 1324 tdp->t_fndef->fn_args = xcalloc(sizeof (tdesc_t) * 1325 vlen - tdp->t_fndef->fn_vargs); 1326 1327 for (i = 0; i < vlen; i++) { 1328 v = (void *) dptr; 1329 memcpy(&argid, v, idwidth); 1330 dptr += idwidth; 1331 1332 if (argid != 0) 1333 tdp->t_fndef->fn_args[i] = tdarr[argid]; 1334 } 1335 1336 dptr = (caddr_t) roundup2((uintptr_t) dptr, 4); 1337 break; 1338 1339 case CTF_K_RESTRICT: 1340 tdp->t_type = RESTRICT; 1341 tdp->t_tdesc = tdarr[type]; 1342 break; 1343 1344 case CTF_K_UNKNOWN: 1345 break; 1346 1347 default: 1348 warning("Can't parse unknown CTF type %d\n", kind); 1349 } 1350 1351 if (isroot) { 1352 iidesc_t *ii = iidesc_new(tdp->t_name); 1353 if (tdp->t_type == STRUCT || tdp->t_type == UNION || 1354 tdp->t_type == ENUM) 1355 ii->ii_type = II_SOU; 1356 else 1357 ii->ii_type = II_TYPE; 1358 ii->ii_dtype = tdp; 1359 hash_add(td->td_iihash, ii); 1360 1361 iicnt++; 1362 } 1363 1364 debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type, 1365 (isroot ? "root " : ""), tdesc_name(tdp), tdp->t_id); 1366 } 1367 1368 debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt); 1369 } 1370 1371 /* 1372 * For lack of other inspiration, we're going to take the boring route. We 1373 * count the number of types. This lets us malloc that many tdesc structs 1374 * before we start filling them in. This has the advantage of allowing us to 1375 * avoid a merge-esque remap step. 1376 */ 1377 static tdata_t * 1378 ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label) 1379 { 1380 tdata_t *td = tdata_new(); 1381 tdesc_t **tdarr; 1382 int ntypes = count_types(h, buf); 1383 int idx, i; 1384 1385 /* shudder */ 1386 tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1)); 1387 tdarr[0] = NULL; 1388 for (i = 1; i <= ntypes; i++) { 1389 tdarr[i] = xcalloc(sizeof (tdesc_t)); 1390 tdarr[i]->t_id = i; 1391 } 1392 1393 td->td_parlabel = xstrdup(buf + h->cth_stroff + h->cth_parlabel); 1394 1395 /* we have the technology - we can rebuild them */ 1396 idx = resurrect_labels(h, td, buf, label); 1397 1398 resurrect_objects(h, td, tdarr, ntypes + 1, buf, si); 1399 resurrect_functions(h, td, tdarr, ntypes + 1, buf, si); 1400 resurrect_types(h, td, tdarr, ntypes + 1, buf, idx); 1401 1402 free(tdarr); 1403 1404 td->td_nextid = ntypes + 1; 1405 1406 return (td); 1407 } 1408 1409 static size_t 1410 decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) 1411 { 1412 z_stream zstr; 1413 int rc; 1414 1415 zstr.zalloc = (alloc_func)0; 1416 zstr.zfree = (free_func)0; 1417 zstr.opaque = (voidpf)0; 1418 1419 zstr.next_in = (Bytef *)cbuf; 1420 zstr.avail_in = cbufsz; 1421 zstr.next_out = (Bytef *)dbuf; 1422 zstr.avail_out = dbufsz; 1423 1424 if ((rc = inflateInit(&zstr)) != Z_OK || 1425 (rc = inflate(&zstr, Z_NO_FLUSH)) != Z_STREAM_END || 1426 (rc = inflateEnd(&zstr)) != Z_OK) { 1427 warning("CTF decompress zlib error %s\n", zError(rc)); 1428 return (0); 1429 } 1430 1431 debug(3, "reflated %lu bytes to %lu, pointer at %d\n", 1432 zstr.total_in, zstr.total_out, (caddr_t)zstr.next_in - cbuf); 1433 1434 return (zstr.total_out); 1435 } 1436 1437 /* 1438 * Reconstruct the type tree from a given buffer of CTF data. Only the types 1439 * up to the type associated with the provided label, inclusive, will be 1440 * reconstructed. If a NULL label is provided, all types will be reconstructed. 1441 * 1442 * This function won't work on files that have been uniquified. 1443 */ 1444 tdata_t * 1445 ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label) 1446 { 1447 ctf_header_t *h; 1448 caddr_t ctfdata; 1449 size_t ctfdatasz; 1450 tdata_t *td; 1451 1452 curfile = file; 1453 1454 if (bufsz < sizeof (ctf_header_t)) 1455 parseterminate("Corrupt CTF - short header"); 1456 1457 void *v = (void *) buf; 1458 h = v; 1459 buf += sizeof (ctf_header_t); 1460 bufsz -= sizeof (ctf_header_t); 1461 1462 if (h->cth_magic != CTF_MAGIC) 1463 parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic); 1464 1465 if (h->cth_version != CTF_VERSION_2 && h->cth_version != CTF_VERSION_3) 1466 parseterminate("Unknown CTF version %d", h->cth_version); 1467 1468 ctfdatasz = h->cth_stroff + h->cth_strlen; 1469 if (h->cth_flags & CTF_F_COMPRESS) { 1470 size_t actual; 1471 1472 ctfdata = xmalloc(ctfdatasz); 1473 if ((actual = decompress_ctf(buf, bufsz, ctfdata, ctfdatasz)) != 1474 ctfdatasz) { 1475 parseterminate("Corrupt CTF - short decompression " 1476 "(was %d, expecting %d)", actual, ctfdatasz); 1477 } 1478 } else { 1479 ctfdata = buf; 1480 ctfdatasz = bufsz; 1481 } 1482 1483 td = ctf_parse(h, ctfdata, si, label); 1484 1485 if (h->cth_flags & CTF_F_COMPRESS) 1486 free(ctfdata); 1487 1488 curfile = NULL; 1489 1490 return (td); 1491 } 1492