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