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 __printflike(1, 2) __dead 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 if (target_requires_swap) { 177 SWAP_16(id); 178 } 179 180 ctf_buf_write(b, &id, sizeof (id)); 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 case REFERENCE: /* XXX: */ 365 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_POINTER, isroot, 0); 366 ctt.ctt_type = tp->t_tdesc->t_id; 367 write_unsized_type_rec(b, &ctt); 368 break; 369 370 case ARRAY: 371 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, isroot, 1); 372 write_sized_type_rec(b, &ctt, tp->t_size); 373 374 cta.cta_contents = tp->t_ardef->ad_contents->t_id; 375 cta.cta_index = tp->t_ardef->ad_idxtype->t_id; 376 cta.cta_nelems = tp->t_ardef->ad_nelems; 377 if (target_requires_swap) { 378 SWAP_16(cta.cta_contents); 379 SWAP_16(cta.cta_index); 380 SWAP_32(cta.cta_nelems); 381 } 382 ctf_buf_write(b, &cta, sizeof (cta)); 383 break; 384 385 case STRUCT: 386 case UNION: 387 case CLASS: 388 for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) 389 i++; /* count up struct or union members */ 390 391 if (i > CTF_MAX_VLEN) { 392 warning("sou %s has too many members: %d > %d\n", 393 tdesc_name(tp), i, CTF_MAX_VLEN); 394 i = CTF_MAX_VLEN; 395 } 396 397 if (tp->t_type == STRUCT) 398 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, isroot, i); 399 else 400 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, isroot, i); 401 402 write_sized_type_rec(b, &ctt, tp->t_size); 403 404 if (tp->t_size < CTF_LSTRUCT_THRESH) { 405 for (mp = tp->t_members; mp != NULL && i > 0; 406 mp = mp->ml_next) { 407 offset = strtab_insert(&b->ctb_strtab, 408 mp->ml_name); 409 410 ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 411 offset); 412 ctm.ctm_type = mp->ml_type->t_id; 413 ctm.ctm_offset = mp->ml_offset; 414 if (target_requires_swap) { 415 SWAP_32(ctm.ctm_name); 416 SWAP_16(ctm.ctm_type); 417 SWAP_16(ctm.ctm_offset); 418 } 419 ctf_buf_write(b, &ctm, sizeof (ctm)); 420 i--; 421 } 422 } else { 423 for (mp = tp->t_members; mp != NULL && i > 0; 424 mp = mp->ml_next) { 425 offset = strtab_insert(&b->ctb_strtab, 426 mp->ml_name); 427 428 ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0, 429 offset); 430 ctlm.ctlm_type = mp->ml_type->t_id; 431 ctlm.ctlm_offsethi = 432 CTF_OFFSET_TO_LMEMHI(mp->ml_offset); 433 ctlm.ctlm_offsetlo = 434 CTF_OFFSET_TO_LMEMLO(mp->ml_offset); 435 436 if (target_requires_swap) { 437 SWAP_32(ctlm.ctlm_name); 438 SWAP_16(ctlm.ctlm_type); 439 SWAP_32(ctlm.ctlm_offsethi); 440 SWAP_32(ctlm.ctlm_offsetlo); 441 } 442 443 ctf_buf_write(b, &ctlm, sizeof (ctlm)); 444 i--; 445 } 446 } 447 break; 448 449 case ENUM: 450 for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next) 451 i++; /* count up enum members */ 452 453 if (i > CTF_MAX_VLEN) { 454 warning("enum %s has too many values: %d > %d\n", 455 tdesc_name(tp), i, CTF_MAX_VLEN); 456 i = CTF_MAX_VLEN; 457 } 458 459 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i); 460 write_sized_type_rec(b, &ctt, tp->t_size); 461 462 for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) { 463 offset = strtab_insert(&b->ctb_strtab, ep->el_name); 464 cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); 465 cte.cte_value = ep->el_number; 466 467 if (target_requires_swap) { 468 SWAP_32(cte.cte_name); 469 SWAP_32(cte.cte_value); 470 } 471 472 ctf_buf_write(b, &cte, sizeof (cte)); 473 i--; 474 } 475 break; 476 477 case FORWARD: 478 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, isroot, 0); 479 ctt.ctt_type = 0; 480 write_unsized_type_rec(b, &ctt); 481 break; 482 483 case TYPEDEF: 484 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0); 485 ctt.ctt_type = tp->t_tdesc->t_id; 486 write_unsized_type_rec(b, &ctt); 487 break; 488 489 case VOLATILE: 490 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_VOLATILE, isroot, 0); 491 ctt.ctt_type = tp->t_tdesc->t_id; 492 write_unsized_type_rec(b, &ctt); 493 break; 494 495 case CONST: 496 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_CONST, isroot, 0); 497 ctt.ctt_type = tp->t_tdesc->t_id; 498 write_unsized_type_rec(b, &ctt); 499 break; 500 501 case FUNCTION: 502 i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs; 503 504 if (i > CTF_MAX_VLEN) { 505 terminate("function %s has too many args: %d > %d\n", 506 tdesc_name(tp), i, CTF_MAX_VLEN); 507 } 508 509 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, i); 510 ctt.ctt_type = tp->t_fndef->fn_ret->t_id; 511 write_unsized_type_rec(b, &ctt); 512 513 for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) { 514 id = tp->t_fndef->fn_args[i]->t_id; 515 516 if (target_requires_swap) { 517 SWAP_16(id); 518 } 519 520 ctf_buf_write(b, &id, sizeof (id)); 521 } 522 523 if (tp->t_fndef->fn_vargs) { 524 id = 0; 525 ctf_buf_write(b, &id, sizeof (id)); 526 i++; 527 } 528 529 if (i & 1) { 530 id = 0; 531 ctf_buf_write(b, &id, sizeof (id)); 532 } 533 break; 534 535 case RESTRICT: 536 ctt.ctt_info = CTF_TYPE_INFO(CTF_K_RESTRICT, isroot, 0); 537 ctt.ctt_type = tp->t_tdesc->t_id; 538 write_unsized_type_rec(b, &ctt); 539 break; 540 541 default: 542 warning("Can't write unknown type %d\n", tp->t_type); 543 } 544 545 debug(3, "Wrote type %d %s\n", tp->t_id, tdesc_name(tp)); 546 547 return (1); 548 } 549 550 typedef struct resbuf { 551 caddr_t rb_base; 552 caddr_t rb_ptr; 553 size_t rb_size; 554 z_stream rb_zstr; 555 } resbuf_t; 556 557 static void 558 rbzs_grow(resbuf_t *rb) 559 { 560 off_t ptroff = (caddr_t)rb->rb_zstr.next_out - rb->rb_base; 561 562 rb->rb_size += RES_BUF_CHUNK_SIZE; 563 rb->rb_base = xrealloc(rb->rb_base, rb->rb_size); 564 rb->rb_ptr = rb->rb_base + ptroff; 565 rb->rb_zstr.next_out = (Bytef *)(rb->rb_ptr); 566 rb->rb_zstr.avail_out += RES_BUF_CHUNK_SIZE; 567 } 568 569 static void 570 compress_start(resbuf_t *rb) 571 { 572 int rc; 573 574 rb->rb_zstr.zalloc = (alloc_func)0; 575 rb->rb_zstr.zfree = (free_func)0; 576 rb->rb_zstr.opaque = (voidpf)0; 577 578 if ((rc = deflateInit(&rb->rb_zstr, Z_BEST_COMPRESSION)) != Z_OK) 579 parseterminate("zlib start failed: %s", zError(rc)); 580 } 581 582 static ssize_t 583 compress_buffer(void *buf, size_t n, void *data) 584 { 585 resbuf_t *rb = (resbuf_t *)data; 586 int rc; 587 588 rb->rb_zstr.next_out = (Bytef *)rb->rb_ptr; 589 rb->rb_zstr.avail_out = rb->rb_size - (rb->rb_ptr - rb->rb_base); 590 rb->rb_zstr.next_in = buf; 591 rb->rb_zstr.avail_in = n; 592 593 while (rb->rb_zstr.avail_in) { 594 if (rb->rb_zstr.avail_out == 0) 595 rbzs_grow(rb); 596 597 if ((rc = deflate(&rb->rb_zstr, Z_NO_FLUSH)) != Z_OK) 598 parseterminate("zlib deflate failed: %s", zError(rc)); 599 } 600 rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 601 602 return (n); 603 } 604 605 static void 606 compress_flush(resbuf_t *rb, int type) 607 { 608 int rc; 609 610 for (;;) { 611 if (rb->rb_zstr.avail_out == 0) 612 rbzs_grow(rb); 613 614 rc = deflate(&rb->rb_zstr, type); 615 if ((type == Z_FULL_FLUSH && rc == Z_BUF_ERROR) || 616 (type == Z_FINISH && rc == Z_STREAM_END)) 617 break; 618 else if (rc != Z_OK) 619 parseterminate("zlib finish failed: %s", zError(rc)); 620 } 621 rb->rb_ptr = (caddr_t)rb->rb_zstr.next_out; 622 } 623 624 static void 625 compress_end(resbuf_t *rb) 626 { 627 int rc; 628 629 compress_flush(rb, Z_FINISH); 630 631 if ((rc = deflateEnd(&rb->rb_zstr)) != Z_OK) 632 parseterminate("zlib end failed: %s", zError(rc)); 633 } 634 635 /* 636 * Pad the buffer to a power-of-2 boundary 637 */ 638 static void 639 pad_buffer(ctf_buf_t *buf, int align) 640 { 641 uint_t cur = ctf_buf_cur(buf); 642 ssize_t topad = (align - (cur % align)) % align; 643 static const char pad[8] = { 0 }; 644 645 while (topad > 0) { 646 ctf_buf_write(buf, pad, (topad > 8 ? 8 : topad)); 647 topad -= 8; 648 } 649 } 650 651 static ssize_t 652 bcopy_data(void *buf, size_t n, void *data) 653 { 654 caddr_t *posp = (caddr_t *)data; 655 bcopy(buf, *posp, n); 656 *posp += n; 657 return (n); 658 } 659 660 static caddr_t 661 write_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 662 { 663 caddr_t outbuf; 664 caddr_t bufpos; 665 666 outbuf = xmalloc(sizeof (ctf_header_t) + (buf->ctb_ptr - buf->ctb_base) 667 + buf->ctb_strtab.str_size); 668 669 bufpos = outbuf; 670 (void) bcopy_data(h, sizeof (ctf_header_t), &bufpos); 671 (void) bcopy_data(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 672 &bufpos); 673 (void) strtab_write(&buf->ctb_strtab, bcopy_data, &bufpos); 674 *resszp = bufpos - outbuf; 675 return (outbuf); 676 } 677 678 /* 679 * Create the compression buffer, and fill it with the CTF and string 680 * table data. We flush the compression state between the two so the 681 * dictionary used for the string tables won't be polluted with values 682 * that made sense for the CTF data. 683 */ 684 static caddr_t 685 write_compressed_buffer(ctf_header_t *h, ctf_buf_t *buf, size_t *resszp) 686 { 687 resbuf_t resbuf; 688 resbuf.rb_size = RES_BUF_CHUNK_SIZE; 689 resbuf.rb_base = xmalloc(resbuf.rb_size); 690 bcopy(h, resbuf.rb_base, sizeof (ctf_header_t)); 691 resbuf.rb_ptr = resbuf.rb_base + sizeof (ctf_header_t); 692 693 compress_start(&resbuf); 694 (void) compress_buffer(buf->ctb_base, buf->ctb_ptr - buf->ctb_base, 695 &resbuf); 696 compress_flush(&resbuf, Z_FULL_FLUSH); 697 (void) strtab_write(&buf->ctb_strtab, compress_buffer, &resbuf); 698 compress_end(&resbuf); 699 700 *resszp = (resbuf.rb_ptr - resbuf.rb_base); 701 return (resbuf.rb_base); 702 } 703 704 caddr_t 705 ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) 706 { 707 ctf_buf_t *buf = ctf_buf_new(); 708 ctf_header_t h; 709 caddr_t outbuf; 710 711 int i; 712 713 target_requires_swap = do_compress & CTF_SWAP_BYTES; 714 do_compress &= ~CTF_SWAP_BYTES; 715 716 /* 717 * Prepare the header, and create the CTF output buffers. The data 718 * object section and function section are both lists of 2-byte 719 * integers; we pad these out to the next 4-byte boundary if needed. 720 */ 721 h.cth_magic = CTF_MAGIC; 722 h.cth_version = CTF_VERSION; 723 h.cth_flags = do_compress ? CTF_F_COMPRESS : 0; 724 h.cth_parlabel = strtab_insert(&buf->ctb_strtab, 725 iiburst->iib_td->td_parlabel); 726 h.cth_parname = strtab_insert(&buf->ctb_strtab, 727 iiburst->iib_td->td_parname); 728 729 h.cth_lbloff = 0; 730 (void) list_iter(iiburst->iib_td->td_labels, write_label, 731 buf); 732 733 pad_buffer(buf, 2); 734 h.cth_objtoff = ctf_buf_cur(buf); 735 for (i = 0; i < iiburst->iib_nobjts; i++) 736 write_objects(iiburst->iib_objts[i], buf); 737 738 pad_buffer(buf, 2); 739 h.cth_funcoff = ctf_buf_cur(buf); 740 for (i = 0; i < iiburst->iib_nfuncs; i++) 741 write_functions(iiburst->iib_funcs[i], buf); 742 743 pad_buffer(buf, 4); 744 h.cth_typeoff = ctf_buf_cur(buf); 745 (void) list_iter(iiburst->iib_types, write_type, buf); 746 747 debug(2, "CTF wrote %d types\n", list_count(iiburst->iib_types)); 748 749 h.cth_stroff = ctf_buf_cur(buf); 750 h.cth_strlen = strtab_size(&buf->ctb_strtab); 751 752 if (target_requires_swap) { 753 SWAP_16(h.cth_preamble.ctp_magic); 754 SWAP_32(h.cth_parlabel); 755 SWAP_32(h.cth_parname); 756 SWAP_32(h.cth_lbloff); 757 SWAP_32(h.cth_objtoff); 758 SWAP_32(h.cth_funcoff); 759 SWAP_32(h.cth_typeoff); 760 SWAP_32(h.cth_stroff); 761 SWAP_32(h.cth_strlen); 762 } 763 764 /* 765 * We only do compression for ctfmerge, as ctfconvert is only 766 * supposed to be used on intermediary build objects. This is 767 * significantly faster. 768 */ 769 if (do_compress) 770 outbuf = write_compressed_buffer(&h, buf, resszp); 771 else 772 outbuf = write_buffer(&h, buf, resszp); 773 774 ctf_buf_free(buf); 775 return (outbuf); 776 } 777 778 static void 779 get_ctt_size(ctf_type_t *ctt, size_t *sizep, size_t *incrementp) 780 { 781 if (ctt->ctt_size == CTF_LSIZE_SENT) { 782 *sizep = (size_t)CTF_TYPE_LSIZE(ctt); 783 *incrementp = sizeof (ctf_type_t); 784 } else { 785 *sizep = ctt->ctt_size; 786 *incrementp = sizeof (ctf_stype_t); 787 } 788 } 789 790 static int 791 count_types(ctf_header_t *h, caddr_t data) 792 { 793 caddr_t dptr = data + h->cth_typeoff; 794 int count = 0; 795 796 dptr = data + h->cth_typeoff; 797 while (dptr < data + h->cth_stroff) { 798 void *v = (void *) dptr; 799 ctf_type_t *ctt = v; 800 size_t vlen = CTF_INFO_VLEN(ctt->ctt_info); 801 size_t size, increment; 802 803 get_ctt_size(ctt, &size, &increment); 804 805 switch (CTF_INFO_KIND(ctt->ctt_info)) { 806 case CTF_K_INTEGER: 807 case CTF_K_FLOAT: 808 dptr += 4; 809 break; 810 case CTF_K_POINTER: 811 case CTF_K_FORWARD: 812 case CTF_K_TYPEDEF: 813 case CTF_K_VOLATILE: 814 case CTF_K_CONST: 815 case CTF_K_RESTRICT: 816 case CTF_K_FUNCTION: 817 dptr += sizeof (ushort_t) * (vlen + (vlen & 1)); 818 break; 819 case CTF_K_ARRAY: 820 dptr += sizeof (ctf_array_t); 821 break; 822 case CTF_K_STRUCT: 823 case CTF_K_UNION: 824 if (size < CTF_LSTRUCT_THRESH) 825 dptr += sizeof (ctf_member_t) * vlen; 826 else 827 dptr += sizeof (ctf_lmember_t) * vlen; 828 break; 829 case CTF_K_ENUM: 830 dptr += sizeof (ctf_enum_t) * vlen; 831 break; 832 case CTF_K_UNKNOWN: 833 break; 834 default: 835 parseterminate("Unknown CTF type %d (#%d) at %#jx", 836 CTF_INFO_KIND(ctt->ctt_info), count, 837 (intmax_t)(dptr - data)); 838 } 839 840 dptr += increment; 841 count++; 842 } 843 844 debug(3, "CTF read %d types\n", count); 845 846 return (count); 847 } 848 849 /* 850 * Resurrect the labels stored in the CTF data, returning the index associated 851 * with a label provided by the caller. There are several cases, outlined 852 * below. Note that, given two labels, the one associated with the lesser type 853 * index is considered to be older than the other. 854 * 855 * 1. matchlbl == NULL - return the index of the most recent label. 856 * 2. matchlbl == "BASE" - return the index of the oldest label. 857 * 3. matchlbl != NULL, but doesn't match any labels in the section - warn 858 * the user, and proceed as if matchlbl == "BASE" (for safety). 859 * 4. matchlbl != NULL, and matches one of the labels in the section - return 860 * the type index associated with the label. 861 */ 862 static int 863 resurrect_labels(ctf_header_t *h, tdata_t *td, caddr_t ctfdata, char *matchlbl) 864 { 865 caddr_t buf = ctfdata + h->cth_lbloff; 866 caddr_t sbuf = ctfdata + h->cth_stroff; 867 size_t bufsz = h->cth_objtoff - h->cth_lbloff; 868 int lastidx = 0, baseidx = -1; 869 char *baselabel = NULL; 870 ctf_lblent_t *ctl; 871 void *v = (void *) buf; 872 873 for (ctl = v; (caddr_t)ctl < buf + bufsz; ctl++) { 874 char *label = sbuf + ctl->ctl_label; 875 876 lastidx = ctl->ctl_typeidx; 877 878 debug(3, "Resurrected label %s type idx %d\n", label, lastidx); 879 880 tdata_label_add(td, label, lastidx); 881 882 if (baseidx == -1) { 883 baseidx = lastidx; 884 baselabel = label; 885 if (matchlbl != NULL && streq(matchlbl, "BASE")) 886 return (lastidx); 887 } 888 889 if (matchlbl != NULL && streq(label, matchlbl)) 890 return (lastidx); 891 } 892 893 if (matchlbl != NULL) { 894 /* User provided a label that didn't match */ 895 warning("%s: Cannot find label `%s' - using base (%s)\n", 896 curfile, matchlbl, (baselabel ? baselabel : "NONE")); 897 898 tdata_label_free(td); 899 tdata_label_add(td, baselabel, baseidx); 900 901 return (baseidx); 902 } 903 904 return (lastidx); 905 } 906 907 static void 908 resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 909 caddr_t ctfdata, symit_data_t *si) 910 { 911 caddr_t buf = ctfdata + h->cth_objtoff; 912 size_t bufsz = h->cth_funcoff - h->cth_objtoff; 913 caddr_t dptr; 914 915 symit_reset(si); 916 for (dptr = buf; dptr < buf + bufsz; dptr += 2) { 917 void *v = (void *) dptr; 918 ushort_t id = *((ushort_t *)v); 919 iidesc_t *ii; 920 GElf_Sym *sym; 921 922 if (!(sym = symit_next(si, STT_OBJECT)) && id != 0) { 923 parseterminate( 924 "Unexpected end of object symbols at %ju of %zu", 925 (intmax_t)(dptr - buf), bufsz); 926 } 927 928 if (id == 0) { 929 debug(3, "Skipping null object\n"); 930 continue; 931 } else if (id >= tdsize) { 932 parseterminate("Reference to invalid type %d", id); 933 } 934 935 ii = iidesc_new(symit_name(si)); 936 ii->ii_dtype = tdarr[id]; 937 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 938 ii->ii_type = II_SVAR; 939 ii->ii_owner = xstrdup(symit_curfile(si)); 940 } else 941 ii->ii_type = II_GVAR; 942 hash_add(td->td_iihash, ii); 943 944 debug(3, "Resurrected %s object %s (%d) from %s\n", 945 (ii->ii_type == II_GVAR ? "global" : "static"), 946 ii->ii_name, id, (ii->ii_owner ? ii->ii_owner : "(none)")); 947 } 948 } 949 950 static void 951 resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 952 caddr_t ctfdata, symit_data_t *si) 953 { 954 caddr_t buf = ctfdata + h->cth_funcoff; 955 size_t bufsz = h->cth_typeoff - h->cth_funcoff; 956 caddr_t dptr = buf; 957 iidesc_t *ii; 958 ushort_t info; 959 ushort_t retid; 960 GElf_Sym *sym; 961 int i; 962 963 symit_reset(si); 964 while (dptr < buf + bufsz) { 965 void *v = (void *) dptr; 966 info = *((ushort_t *)v); 967 dptr += 2; 968 969 if (!(sym = symit_next(si, STT_FUNC)) && info != 0) 970 parseterminate("Unexpected end of function symbols"); 971 972 if (info == 0) { 973 debug(3, "Skipping null function (%s)\n", 974 symit_name(si)); 975 continue; 976 } 977 978 v = (void *) dptr; 979 retid = *((ushort_t *)v); 980 dptr += 2; 981 982 if (retid >= tdsize) 983 parseterminate("Reference to invalid type %d", retid); 984 985 ii = iidesc_new(symit_name(si)); 986 ii->ii_dtype = tdarr[retid]; 987 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 988 ii->ii_type = II_SFUN; 989 ii->ii_owner = xstrdup(symit_curfile(si)); 990 } else 991 ii->ii_type = II_GFUN; 992 ii->ii_nargs = CTF_INFO_VLEN(info); 993 if (ii->ii_nargs) 994 ii->ii_args = 995 xmalloc(sizeof (tdesc_t *) * ii->ii_nargs); 996 997 for (i = 0; i < ii->ii_nargs; i++, dptr += 2) { 998 v = (void *) dptr; 999 ushort_t id = *((ushort_t *)v); 1000 if (id >= tdsize) 1001 parseterminate("Reference to invalid type %d", 1002 id); 1003 ii->ii_args[i] = tdarr[id]; 1004 } 1005 1006 if (ii->ii_nargs && ii->ii_args[ii->ii_nargs - 1] == NULL) { 1007 ii->ii_nargs--; 1008 ii->ii_vargs = 1; 1009 } 1010 1011 hash_add(td->td_iihash, ii); 1012 1013 debug(3, "Resurrected %s function %s (%d, %d args)\n", 1014 (ii->ii_type == II_GFUN ? "global" : "static"), 1015 ii->ii_name, retid, ii->ii_nargs); 1016 } 1017 } 1018 1019 static void 1020 resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 1021 caddr_t ctfdata, int maxid) 1022 { 1023 caddr_t buf = ctfdata + h->cth_typeoff; 1024 size_t bufsz = h->cth_stroff - h->cth_typeoff; 1025 caddr_t sbuf = ctfdata + h->cth_stroff; 1026 caddr_t dptr = buf; 1027 tdesc_t *tdp; 1028 uint_t data; 1029 uint_t encoding; 1030 size_t size, increment; 1031 int tcnt; 1032 int iicnt = 0; 1033 tid_t tid, argid; 1034 int kind, vlen; 1035 int i; 1036 1037 elist_t **epp; 1038 mlist_t **mpp; 1039 intr_t *ip; 1040 1041 ctf_type_t *ctt; 1042 ctf_array_t *cta; 1043 ctf_enum_t *cte; 1044 1045 /* 1046 * A maxid of zero indicates a request to resurrect all types, so reset 1047 * maxid to the maximum type id. 1048 */ 1049 if (maxid == 0) 1050 maxid = CTF_MAX_TYPE; 1051 1052 for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) { 1053 if (tid > maxid) 1054 break; 1055 1056 if (tid >= tdsize) 1057 parseterminate("Reference to invalid type %d", tid); 1058 1059 void *v = (void *) dptr; 1060 ctt = v; 1061 1062 get_ctt_size(ctt, &size, &increment); 1063 dptr += increment; 1064 1065 tdp = tdarr[tid]; 1066 1067 if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0) 1068 parseterminate( 1069 "Unable to cope with non-zero strtab id"); 1070 if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) { 1071 tdp->t_name = 1072 xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name)); 1073 } else 1074 tdp->t_name = NULL; 1075 1076 kind = CTF_INFO_KIND(ctt->ctt_info); 1077 vlen = CTF_INFO_VLEN(ctt->ctt_info); 1078 1079 switch (kind) { 1080 case CTF_K_INTEGER: 1081 tdp->t_type = INTRINSIC; 1082 tdp->t_size = size; 1083 1084 v = (void *) dptr; 1085 data = *((uint_t *)v); 1086 dptr += sizeof (uint_t); 1087 encoding = CTF_INT_ENCODING(data); 1088 1089 ip = xmalloc(sizeof (intr_t)); 1090 ip->intr_type = INTR_INT; 1091 ip->intr_signed = (encoding & CTF_INT_SIGNED) ? 1 : 0; 1092 1093 if (encoding & CTF_INT_CHAR) 1094 ip->intr_iformat = 'c'; 1095 else if (encoding & CTF_INT_BOOL) 1096 ip->intr_iformat = 'b'; 1097 else if (encoding & CTF_INT_VARARGS) 1098 ip->intr_iformat = 'v'; 1099 else 1100 ip->intr_iformat = '\0'; 1101 1102 ip->intr_offset = CTF_INT_OFFSET(data); 1103 ip->intr_nbits = CTF_INT_BITS(data); 1104 tdp->t_intr = ip; 1105 break; 1106 1107 case CTF_K_FLOAT: 1108 tdp->t_type = INTRINSIC; 1109 tdp->t_size = size; 1110 1111 v = (void *) dptr; 1112 data = *((uint_t *)v); 1113 dptr += sizeof (uint_t); 1114 1115 ip = xcalloc(sizeof (intr_t)); 1116 ip->intr_type = INTR_REAL; 1117 ip->intr_fformat = CTF_FP_ENCODING(data); 1118 ip->intr_offset = CTF_FP_OFFSET(data); 1119 ip->intr_nbits = CTF_FP_BITS(data); 1120 tdp->t_intr = ip; 1121 break; 1122 1123 case CTF_K_POINTER: 1124 tdp->t_type = POINTER; 1125 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1126 break; 1127 1128 case CTF_K_ARRAY: 1129 tdp->t_type = ARRAY; 1130 tdp->t_size = size; 1131 1132 v = (void *) dptr; 1133 cta = v; 1134 dptr += sizeof (ctf_array_t); 1135 1136 tdp->t_ardef = xmalloc(sizeof (ardef_t)); 1137 tdp->t_ardef->ad_contents = tdarr[cta->cta_contents]; 1138 tdp->t_ardef->ad_idxtype = tdarr[cta->cta_index]; 1139 tdp->t_ardef->ad_nelems = cta->cta_nelems; 1140 break; 1141 1142 case CTF_K_STRUCT: 1143 case CTF_K_UNION: 1144 tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION); 1145 tdp->t_size = size; 1146 1147 if (size < CTF_LSTRUCT_THRESH) { 1148 for (i = 0, mpp = &tdp->t_members; i < vlen; 1149 i++, mpp = &((*mpp)->ml_next)) { 1150 v = (void *) dptr; 1151 ctf_member_t *ctm = v; 1152 dptr += sizeof (ctf_member_t); 1153 1154 *mpp = xmalloc(sizeof (mlist_t)); 1155 (*mpp)->ml_name = xstrdup(sbuf + 1156 ctm->ctm_name); 1157 (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1158 (*mpp)->ml_offset = ctm->ctm_offset; 1159 (*mpp)->ml_size = 0; 1160 if (ctm->ctm_type > ntypes) { 1161 parseterminate("Invalid member type ctm_type=%d", 1162 ctm->ctm_type); 1163 } 1164 } 1165 } else { 1166 for (i = 0, mpp = &tdp->t_members; i < vlen; 1167 i++, mpp = &((*mpp)->ml_next)) { 1168 v = (void *) dptr; 1169 ctf_lmember_t *ctlm = v; 1170 dptr += sizeof (ctf_lmember_t); 1171 1172 *mpp = xmalloc(sizeof (mlist_t)); 1173 (*mpp)->ml_name = xstrdup(sbuf + 1174 ctlm->ctlm_name); 1175 (*mpp)->ml_type = 1176 tdarr[ctlm->ctlm_type]; 1177 (*mpp)->ml_offset = 1178 (int)CTF_LMEM_OFFSET(ctlm); 1179 (*mpp)->ml_size = 0; 1180 if (ctlm->ctlm_type > ntypes) { 1181 parseterminate("Invalid lmember type ctlm_type=%d", 1182 ctlm->ctlm_type); 1183 } 1184 } 1185 } 1186 1187 *mpp = NULL; 1188 break; 1189 1190 case CTF_K_ENUM: 1191 tdp->t_type = ENUM; 1192 tdp->t_size = size; 1193 1194 for (i = 0, epp = &tdp->t_emem; i < vlen; 1195 i++, epp = &((*epp)->el_next)) { 1196 v = (void *) dptr; 1197 cte = v; 1198 dptr += sizeof (ctf_enum_t); 1199 1200 *epp = xmalloc(sizeof (elist_t)); 1201 (*epp)->el_name = xstrdup(sbuf + cte->cte_name); 1202 (*epp)->el_number = cte->cte_value; 1203 } 1204 *epp = NULL; 1205 break; 1206 1207 case CTF_K_FORWARD: 1208 tdp->t_type = FORWARD; 1209 list_add(&td->td_fwdlist, tdp); 1210 break; 1211 1212 case CTF_K_TYPEDEF: 1213 tdp->t_type = TYPEDEF; 1214 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1215 break; 1216 1217 case CTF_K_VOLATILE: 1218 tdp->t_type = VOLATILE; 1219 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1220 break; 1221 1222 case CTF_K_CONST: 1223 tdp->t_type = CONST; 1224 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1225 break; 1226 1227 case CTF_K_FUNCTION: 1228 tdp->t_type = FUNCTION; 1229 tdp->t_fndef = xcalloc(sizeof (fndef_t)); 1230 tdp->t_fndef->fn_ret = tdarr[ctt->ctt_type]; 1231 1232 v = (void *) (dptr + (sizeof (ushort_t) * (vlen - 1))); 1233 if (vlen > 0 && *(ushort_t *)v == 0) 1234 tdp->t_fndef->fn_vargs = 1; 1235 1236 tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs; 1237 tdp->t_fndef->fn_args = xcalloc(sizeof (tdesc_t) * 1238 vlen - tdp->t_fndef->fn_vargs); 1239 1240 for (i = 0; i < vlen; i++) { 1241 v = (void *) dptr; 1242 argid = *(ushort_t *)v; 1243 dptr += sizeof (ushort_t); 1244 1245 if (argid != 0) 1246 tdp->t_fndef->fn_args[i] = tdarr[argid]; 1247 } 1248 1249 if (vlen & 1) 1250 dptr += sizeof (ushort_t); 1251 break; 1252 1253 case CTF_K_RESTRICT: 1254 tdp->t_type = RESTRICT; 1255 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1256 break; 1257 1258 case CTF_K_UNKNOWN: 1259 break; 1260 1261 default: 1262 warning("Can't parse unknown CTF type %d\n", kind); 1263 } 1264 1265 if (CTF_INFO_ISROOT(ctt->ctt_info)) { 1266 iidesc_t *ii = iidesc_new(tdp->t_name); 1267 if (tdp->t_type == STRUCT || tdp->t_type == UNION || 1268 tdp->t_type == ENUM) 1269 ii->ii_type = II_SOU; 1270 else 1271 ii->ii_type = II_TYPE; 1272 ii->ii_dtype = tdp; 1273 hash_add(td->td_iihash, ii); 1274 1275 iicnt++; 1276 } 1277 1278 debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type, 1279 (CTF_INFO_ISROOT(ctt->ctt_info) ? "root " : ""), 1280 tdesc_name(tdp), tdp->t_id); 1281 } 1282 1283 debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt); 1284 } 1285 1286 /* 1287 * For lack of other inspiration, we're going to take the boring route. We 1288 * count the number of types. This lets us malloc that many tdesc structs 1289 * before we start filling them in. This has the advantage of allowing us to 1290 * avoid a merge-esque remap step. 1291 */ 1292 static tdata_t * 1293 ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label) 1294 { 1295 tdata_t *td = tdata_new(); 1296 tdesc_t **tdarr; 1297 int idx, i; 1298 1299 ntypes = count_types(h, buf); 1300 1301 /* shudder */ 1302 tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1)); 1303 tdarr[0] = NULL; 1304 for (i = 1; i <= ntypes; i++) { 1305 tdarr[i] = xcalloc(sizeof (tdesc_t)); 1306 tdarr[i]->t_id = i; 1307 } 1308 1309 td->td_parlabel = xstrdup(buf + h->cth_stroff + h->cth_parlabel); 1310 1311 /* we have the technology - we can rebuild them */ 1312 idx = resurrect_labels(h, td, buf, label); 1313 1314 resurrect_objects(h, td, tdarr, ntypes + 1, buf, si); 1315 resurrect_functions(h, td, tdarr, ntypes + 1, buf, si); 1316 resurrect_types(h, td, tdarr, ntypes + 1, buf, idx); 1317 1318 free(tdarr); 1319 1320 td->td_nextid = ntypes + 1; 1321 1322 return (td); 1323 } 1324 1325 static size_t 1326 decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) 1327 { 1328 z_stream zstr; 1329 int rc; 1330 1331 zstr.zalloc = (alloc_func)0; 1332 zstr.zfree = (free_func)0; 1333 zstr.opaque = (voidpf)0; 1334 1335 zstr.next_in = (Bytef *)cbuf; 1336 zstr.avail_in = cbufsz; 1337 zstr.next_out = (Bytef *)dbuf; 1338 zstr.avail_out = dbufsz; 1339 1340 if ((rc = inflateInit(&zstr)) != Z_OK || 1341 (rc = inflate(&zstr, Z_NO_FLUSH)) != Z_STREAM_END || 1342 (rc = inflateEnd(&zstr)) != Z_OK) { 1343 warning("CTF decompress zlib error %s\n", zError(rc)); 1344 return (0); 1345 } 1346 1347 debug(3, "reflated %lu bytes to %lu, pointer at 0x%jx\n", 1348 zstr.total_in, zstr.total_out, 1349 (intmax_t)((caddr_t)zstr.next_in - cbuf)); 1350 1351 return (zstr.total_out); 1352 } 1353 1354 /* 1355 * Reconstruct the type tree from a given buffer of CTF data. Only the types 1356 * up to the type associated with the provided label, inclusive, will be 1357 * reconstructed. If a NULL label is provided, all types will be reconstructed. 1358 * 1359 * This function won't work on files that have been uniquified. 1360 */ 1361 tdata_t * 1362 ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label) 1363 { 1364 ctf_header_t *h; 1365 caddr_t ctfdata; 1366 size_t ctfdatasz; 1367 tdata_t *td; 1368 1369 curfile = file; 1370 1371 if (bufsz < sizeof (ctf_header_t)) 1372 parseterminate("Corrupt CTF - short header"); 1373 1374 void *v = (void *) buf; 1375 h = v; 1376 buf += sizeof (ctf_header_t); 1377 bufsz -= sizeof (ctf_header_t); 1378 1379 if (h->cth_magic != CTF_MAGIC) 1380 parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic); 1381 1382 if (h->cth_version != CTF_VERSION) 1383 parseterminate("Unknown CTF version %d", h->cth_version); 1384 1385 ctfdatasz = h->cth_stroff + h->cth_strlen; 1386 if (h->cth_flags & CTF_F_COMPRESS) { 1387 size_t actual; 1388 1389 ctfdata = xmalloc(ctfdatasz); 1390 if ((actual = decompress_ctf(buf, bufsz, ctfdata, ctfdatasz)) != 1391 ctfdatasz) { 1392 parseterminate("Corrupt CTF - short decompression " 1393 "(was %zu, expecting %zu)", actual, ctfdatasz); 1394 } 1395 } else { 1396 ctfdata = buf; 1397 ctfdatasz = bufsz; 1398 } 1399 1400 td = ctf_parse(h, ctfdata, si, label); 1401 1402 if (h->cth_flags & CTF_F_COMPRESS) 1403 free(ctfdata); 1404 1405 curfile = NULL; 1406 1407 return (td); 1408 } 1409