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) 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 tdesc_name(tp), 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 %#jx", 829 CTF_INFO_KIND(ctt->ctt_info), count, 830 (intmax_t)(dptr - data)); 831 } 832 833 dptr += increment; 834 count++; 835 } 836 837 debug(3, "CTF read %d types\n", count); 838 839 return (count); 840 } 841 842 /* 843 * Resurrect the labels stored in the CTF data, returning the index associated 844 * with a label provided by the caller. There are several cases, outlined 845 * below. Note that, given two labels, the one associated with the lesser type 846 * index is considered to be older than the other. 847 * 848 * 1. matchlbl == NULL - return the index of the most recent label. 849 * 2. matchlbl == "BASE" - return the index of the oldest label. 850 * 3. matchlbl != NULL, but doesn't match any labels in the section - warn 851 * the user, and proceed as if matchlbl == "BASE" (for safety). 852 * 4. matchlbl != NULL, and matches one of the labels in the section - return 853 * the type index associated with the label. 854 */ 855 static int 856 resurrect_labels(ctf_header_t *h, tdata_t *td, caddr_t ctfdata, char *matchlbl) 857 { 858 caddr_t buf = ctfdata + h->cth_lbloff; 859 caddr_t sbuf = ctfdata + h->cth_stroff; 860 size_t bufsz = h->cth_objtoff - h->cth_lbloff; 861 int lastidx = 0, baseidx = -1; 862 char *baselabel = NULL; 863 ctf_lblent_t *ctl; 864 void *v = (void *) buf; 865 866 for (ctl = v; (caddr_t)ctl < buf + bufsz; ctl++) { 867 char *label = sbuf + ctl->ctl_label; 868 869 lastidx = ctl->ctl_typeidx; 870 871 debug(3, "Resurrected label %s type idx %d\n", label, lastidx); 872 873 tdata_label_add(td, label, lastidx); 874 875 if (baseidx == -1) { 876 baseidx = lastidx; 877 baselabel = label; 878 if (matchlbl != NULL && streq(matchlbl, "BASE")) 879 return (lastidx); 880 } 881 882 if (matchlbl != NULL && streq(label, matchlbl)) 883 return (lastidx); 884 } 885 886 if (matchlbl != NULL) { 887 /* User provided a label that didn't match */ 888 warning("%s: Cannot find label `%s' - using base (%s)\n", 889 curfile, matchlbl, (baselabel ? baselabel : "NONE")); 890 891 tdata_label_free(td); 892 tdata_label_add(td, baselabel, baseidx); 893 894 return (baseidx); 895 } 896 897 return (lastidx); 898 } 899 900 static void 901 resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 902 caddr_t ctfdata, symit_data_t *si) 903 { 904 caddr_t buf = ctfdata + h->cth_objtoff; 905 size_t bufsz = h->cth_funcoff - h->cth_objtoff; 906 caddr_t dptr; 907 908 symit_reset(si); 909 for (dptr = buf; dptr < buf + bufsz; dptr += 2) { 910 void *v = (void *) dptr; 911 ushort_t id = *((ushort_t *)v); 912 iidesc_t *ii; 913 GElf_Sym *sym; 914 915 if (!(sym = symit_next(si, STT_OBJECT)) && id != 0) { 916 parseterminate( 917 "Unexpected end of object symbols at %ju of %zu", 918 (intmax_t)(dptr - buf), bufsz); 919 } 920 921 if (id == 0) { 922 debug(3, "Skipping null object\n"); 923 continue; 924 } else if (id >= tdsize) { 925 parseterminate("Reference to invalid type %d", id); 926 } 927 928 ii = iidesc_new(symit_name(si)); 929 ii->ii_dtype = tdarr[id]; 930 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 931 ii->ii_type = II_SVAR; 932 ii->ii_owner = xstrdup(symit_curfile(si)); 933 } else 934 ii->ii_type = II_GVAR; 935 hash_add(td->td_iihash, ii); 936 937 debug(3, "Resurrected %s object %s (%d) from %s\n", 938 (ii->ii_type == II_GVAR ? "global" : "static"), 939 ii->ii_name, id, (ii->ii_owner ? ii->ii_owner : "(none)")); 940 } 941 } 942 943 static void 944 resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 945 caddr_t ctfdata, symit_data_t *si) 946 { 947 caddr_t buf = ctfdata + h->cth_funcoff; 948 size_t bufsz = h->cth_typeoff - h->cth_funcoff; 949 caddr_t dptr = buf; 950 iidesc_t *ii; 951 ushort_t info; 952 ushort_t retid; 953 GElf_Sym *sym; 954 int i; 955 956 symit_reset(si); 957 while (dptr < buf + bufsz) { 958 void *v = (void *) dptr; 959 info = *((ushort_t *)v); 960 dptr += 2; 961 962 if (!(sym = symit_next(si, STT_FUNC)) && info != 0) 963 parseterminate("Unexpected end of function symbols"); 964 965 if (info == 0) { 966 debug(3, "Skipping null function (%s)\n", 967 symit_name(si)); 968 continue; 969 } 970 971 v = (void *) dptr; 972 retid = *((ushort_t *)v); 973 dptr += 2; 974 975 if (retid >= tdsize) 976 parseterminate("Reference to invalid type %d", retid); 977 978 ii = iidesc_new(symit_name(si)); 979 ii->ii_dtype = tdarr[retid]; 980 if (GELF_ST_BIND(sym->st_info) == STB_LOCAL) { 981 ii->ii_type = II_SFUN; 982 ii->ii_owner = xstrdup(symit_curfile(si)); 983 } else 984 ii->ii_type = II_GFUN; 985 ii->ii_nargs = CTF_INFO_VLEN(info); 986 if (ii->ii_nargs) 987 ii->ii_args = 988 xmalloc(sizeof (tdesc_t *) * ii->ii_nargs); 989 990 for (i = 0; i < ii->ii_nargs; i++, dptr += 2) { 991 v = (void *) dptr; 992 ushort_t id = *((ushort_t *)v); 993 if (id >= tdsize) 994 parseterminate("Reference to invalid type %d", 995 id); 996 ii->ii_args[i] = tdarr[id]; 997 } 998 999 if (ii->ii_nargs && ii->ii_args[ii->ii_nargs - 1] == NULL) { 1000 ii->ii_nargs--; 1001 ii->ii_vargs = 1; 1002 } 1003 1004 hash_add(td->td_iihash, ii); 1005 1006 debug(3, "Resurrected %s function %s (%d, %d args)\n", 1007 (ii->ii_type == II_GFUN ? "global" : "static"), 1008 ii->ii_name, retid, ii->ii_nargs); 1009 } 1010 } 1011 1012 static void 1013 resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, 1014 caddr_t ctfdata, int maxid) 1015 { 1016 caddr_t buf = ctfdata + h->cth_typeoff; 1017 size_t bufsz = h->cth_stroff - h->cth_typeoff; 1018 caddr_t sbuf = ctfdata + h->cth_stroff; 1019 caddr_t dptr = buf; 1020 tdesc_t *tdp; 1021 uint_t data; 1022 uint_t encoding; 1023 size_t size, increment; 1024 int tcnt; 1025 int iicnt = 0; 1026 tid_t tid, argid; 1027 int kind, vlen; 1028 int i; 1029 1030 elist_t **epp; 1031 mlist_t **mpp; 1032 intr_t *ip; 1033 1034 ctf_type_t *ctt; 1035 ctf_array_t *cta; 1036 ctf_enum_t *cte; 1037 1038 /* 1039 * A maxid of zero indicates a request to resurrect all types, so reset 1040 * maxid to the maximum type id. 1041 */ 1042 if (maxid == 0) 1043 maxid = CTF_MAX_TYPE; 1044 1045 for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) { 1046 if (tid > maxid) 1047 break; 1048 1049 if (tid >= tdsize) 1050 parseterminate("Reference to invalid type %d", tid); 1051 1052 void *v = (void *) dptr; 1053 ctt = v; 1054 1055 get_ctt_size(ctt, &size, &increment); 1056 dptr += increment; 1057 1058 tdp = tdarr[tid]; 1059 1060 if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0) 1061 parseterminate( 1062 "Unable to cope with non-zero strtab id"); 1063 if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) { 1064 tdp->t_name = 1065 xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name)); 1066 } else 1067 tdp->t_name = NULL; 1068 1069 kind = CTF_INFO_KIND(ctt->ctt_info); 1070 vlen = CTF_INFO_VLEN(ctt->ctt_info); 1071 1072 switch (kind) { 1073 case CTF_K_INTEGER: 1074 tdp->t_type = INTRINSIC; 1075 tdp->t_size = size; 1076 1077 v = (void *) dptr; 1078 data = *((uint_t *)v); 1079 dptr += sizeof (uint_t); 1080 encoding = CTF_INT_ENCODING(data); 1081 1082 ip = xmalloc(sizeof (intr_t)); 1083 ip->intr_type = INTR_INT; 1084 ip->intr_signed = (encoding & CTF_INT_SIGNED) ? 1 : 0; 1085 1086 if (encoding & CTF_INT_CHAR) 1087 ip->intr_iformat = 'c'; 1088 else if (encoding & CTF_INT_BOOL) 1089 ip->intr_iformat = 'b'; 1090 else if (encoding & CTF_INT_VARARGS) 1091 ip->intr_iformat = 'v'; 1092 else 1093 ip->intr_iformat = '\0'; 1094 1095 ip->intr_offset = CTF_INT_OFFSET(data); 1096 ip->intr_nbits = CTF_INT_BITS(data); 1097 tdp->t_intr = ip; 1098 break; 1099 1100 case CTF_K_FLOAT: 1101 tdp->t_type = INTRINSIC; 1102 tdp->t_size = size; 1103 1104 v = (void *) dptr; 1105 data = *((uint_t *)v); 1106 dptr += sizeof (uint_t); 1107 1108 ip = xcalloc(sizeof (intr_t)); 1109 ip->intr_type = INTR_REAL; 1110 ip->intr_fformat = CTF_FP_ENCODING(data); 1111 ip->intr_offset = CTF_FP_OFFSET(data); 1112 ip->intr_nbits = CTF_FP_BITS(data); 1113 tdp->t_intr = ip; 1114 break; 1115 1116 case CTF_K_POINTER: 1117 tdp->t_type = POINTER; 1118 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1119 break; 1120 1121 case CTF_K_ARRAY: 1122 tdp->t_type = ARRAY; 1123 tdp->t_size = size; 1124 1125 v = (void *) dptr; 1126 cta = v; 1127 dptr += sizeof (ctf_array_t); 1128 1129 tdp->t_ardef = xmalloc(sizeof (ardef_t)); 1130 tdp->t_ardef->ad_contents = tdarr[cta->cta_contents]; 1131 tdp->t_ardef->ad_idxtype = tdarr[cta->cta_index]; 1132 tdp->t_ardef->ad_nelems = cta->cta_nelems; 1133 break; 1134 1135 case CTF_K_STRUCT: 1136 case CTF_K_UNION: 1137 tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION); 1138 tdp->t_size = size; 1139 1140 if (size < CTF_LSTRUCT_THRESH) { 1141 for (i = 0, mpp = &tdp->t_members; i < vlen; 1142 i++, mpp = &((*mpp)->ml_next)) { 1143 v = (void *) dptr; 1144 ctf_member_t *ctm = v; 1145 dptr += sizeof (ctf_member_t); 1146 1147 *mpp = xmalloc(sizeof (mlist_t)); 1148 (*mpp)->ml_name = xstrdup(sbuf + 1149 ctm->ctm_name); 1150 (*mpp)->ml_type = tdarr[ctm->ctm_type]; 1151 (*mpp)->ml_offset = ctm->ctm_offset; 1152 (*mpp)->ml_size = 0; 1153 if (ctm->ctm_type > ntypes) { 1154 parseterminate("Invalid member type ctm_type=%d", 1155 ctm->ctm_type); 1156 } 1157 } 1158 } else { 1159 for (i = 0, mpp = &tdp->t_members; i < vlen; 1160 i++, mpp = &((*mpp)->ml_next)) { 1161 v = (void *) dptr; 1162 ctf_lmember_t *ctlm = v; 1163 dptr += sizeof (ctf_lmember_t); 1164 1165 *mpp = xmalloc(sizeof (mlist_t)); 1166 (*mpp)->ml_name = xstrdup(sbuf + 1167 ctlm->ctlm_name); 1168 (*mpp)->ml_type = 1169 tdarr[ctlm->ctlm_type]; 1170 (*mpp)->ml_offset = 1171 (int)CTF_LMEM_OFFSET(ctlm); 1172 (*mpp)->ml_size = 0; 1173 if (ctlm->ctlm_type > ntypes) { 1174 parseterminate("Invalid lmember type ctlm_type=%d", 1175 ctlm->ctlm_type); 1176 } 1177 } 1178 } 1179 1180 *mpp = NULL; 1181 break; 1182 1183 case CTF_K_ENUM: 1184 tdp->t_type = ENUM; 1185 tdp->t_size = size; 1186 1187 for (i = 0, epp = &tdp->t_emem; i < vlen; 1188 i++, epp = &((*epp)->el_next)) { 1189 v = (void *) dptr; 1190 cte = v; 1191 dptr += sizeof (ctf_enum_t); 1192 1193 *epp = xmalloc(sizeof (elist_t)); 1194 (*epp)->el_name = xstrdup(sbuf + cte->cte_name); 1195 (*epp)->el_number = cte->cte_value; 1196 } 1197 *epp = NULL; 1198 break; 1199 1200 case CTF_K_FORWARD: 1201 tdp->t_type = FORWARD; 1202 list_add(&td->td_fwdlist, tdp); 1203 break; 1204 1205 case CTF_K_TYPEDEF: 1206 tdp->t_type = TYPEDEF; 1207 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1208 break; 1209 1210 case CTF_K_VOLATILE: 1211 tdp->t_type = VOLATILE; 1212 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1213 break; 1214 1215 case CTF_K_CONST: 1216 tdp->t_type = CONST; 1217 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1218 break; 1219 1220 case CTF_K_FUNCTION: 1221 tdp->t_type = FUNCTION; 1222 tdp->t_fndef = xcalloc(sizeof (fndef_t)); 1223 tdp->t_fndef->fn_ret = tdarr[ctt->ctt_type]; 1224 1225 v = (void *) (dptr + (sizeof (ushort_t) * (vlen - 1))); 1226 if (vlen > 0 && *(ushort_t *)v == 0) 1227 tdp->t_fndef->fn_vargs = 1; 1228 1229 tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs; 1230 tdp->t_fndef->fn_args = xcalloc(sizeof (tdesc_t) * 1231 vlen - tdp->t_fndef->fn_vargs); 1232 1233 for (i = 0; i < vlen; i++) { 1234 v = (void *) dptr; 1235 argid = *(ushort_t *)v; 1236 dptr += sizeof (ushort_t); 1237 1238 if (argid != 0) 1239 tdp->t_fndef->fn_args[i] = tdarr[argid]; 1240 } 1241 1242 if (vlen & 1) 1243 dptr += sizeof (ushort_t); 1244 break; 1245 1246 case CTF_K_RESTRICT: 1247 tdp->t_type = RESTRICT; 1248 tdp->t_tdesc = tdarr[ctt->ctt_type]; 1249 break; 1250 1251 case CTF_K_UNKNOWN: 1252 break; 1253 1254 default: 1255 warning("Can't parse unknown CTF type %d\n", kind); 1256 } 1257 1258 if (CTF_INFO_ISROOT(ctt->ctt_info)) { 1259 iidesc_t *ii = iidesc_new(tdp->t_name); 1260 if (tdp->t_type == STRUCT || tdp->t_type == UNION || 1261 tdp->t_type == ENUM) 1262 ii->ii_type = II_SOU; 1263 else 1264 ii->ii_type = II_TYPE; 1265 ii->ii_dtype = tdp; 1266 hash_add(td->td_iihash, ii); 1267 1268 iicnt++; 1269 } 1270 1271 debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type, 1272 (CTF_INFO_ISROOT(ctt->ctt_info) ? "root " : ""), 1273 tdesc_name(tdp), tdp->t_id); 1274 } 1275 1276 debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt); 1277 } 1278 1279 /* 1280 * For lack of other inspiration, we're going to take the boring route. We 1281 * count the number of types. This lets us malloc that many tdesc structs 1282 * before we start filling them in. This has the advantage of allowing us to 1283 * avoid a merge-esque remap step. 1284 */ 1285 static tdata_t * 1286 ctf_parse(ctf_header_t *h, caddr_t buf, symit_data_t *si, char *label) 1287 { 1288 tdata_t *td = tdata_new(); 1289 tdesc_t **tdarr; 1290 int idx, i; 1291 1292 ntypes = count_types(h, buf); 1293 1294 /* shudder */ 1295 tdarr = xcalloc(sizeof (tdesc_t *) * (ntypes + 1)); 1296 tdarr[0] = NULL; 1297 for (i = 1; i <= ntypes; i++) { 1298 tdarr[i] = xcalloc(sizeof (tdesc_t)); 1299 tdarr[i]->t_id = i; 1300 } 1301 1302 td->td_parlabel = xstrdup(buf + h->cth_stroff + h->cth_parlabel); 1303 1304 /* we have the technology - we can rebuild them */ 1305 idx = resurrect_labels(h, td, buf, label); 1306 1307 resurrect_objects(h, td, tdarr, ntypes + 1, buf, si); 1308 resurrect_functions(h, td, tdarr, ntypes + 1, buf, si); 1309 resurrect_types(h, td, tdarr, ntypes + 1, buf, idx); 1310 1311 free(tdarr); 1312 1313 td->td_nextid = ntypes + 1; 1314 1315 return (td); 1316 } 1317 1318 static size_t 1319 decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) 1320 { 1321 z_stream zstr; 1322 int rc; 1323 1324 zstr.zalloc = (alloc_func)0; 1325 zstr.zfree = (free_func)0; 1326 zstr.opaque = (voidpf)0; 1327 1328 zstr.next_in = (Bytef *)cbuf; 1329 zstr.avail_in = cbufsz; 1330 zstr.next_out = (Bytef *)dbuf; 1331 zstr.avail_out = dbufsz; 1332 1333 if ((rc = inflateInit(&zstr)) != Z_OK || 1334 (rc = inflate(&zstr, Z_NO_FLUSH)) != Z_STREAM_END || 1335 (rc = inflateEnd(&zstr)) != Z_OK) { 1336 warning("CTF decompress zlib error %s\n", zError(rc)); 1337 return (0); 1338 } 1339 1340 debug(3, "reflated %lu bytes to %lu, pointer at 0x%jx\n", 1341 zstr.total_in, zstr.total_out, 1342 (intmax_t)((caddr_t)zstr.next_in - cbuf)); 1343 1344 return (zstr.total_out); 1345 } 1346 1347 /* 1348 * Reconstruct the type tree from a given buffer of CTF data. Only the types 1349 * up to the type associated with the provided label, inclusive, will be 1350 * reconstructed. If a NULL label is provided, all types will be reconstructed. 1351 * 1352 * This function won't work on files that have been uniquified. 1353 */ 1354 tdata_t * 1355 ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label) 1356 { 1357 ctf_header_t *h; 1358 caddr_t ctfdata; 1359 size_t ctfdatasz; 1360 tdata_t *td; 1361 1362 curfile = file; 1363 1364 if (bufsz < sizeof (ctf_header_t)) 1365 parseterminate("Corrupt CTF - short header"); 1366 1367 void *v = (void *) buf; 1368 h = v; 1369 buf += sizeof (ctf_header_t); 1370 bufsz -= sizeof (ctf_header_t); 1371 1372 if (h->cth_magic != CTF_MAGIC) 1373 parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic); 1374 1375 if (h->cth_version != CTF_VERSION) 1376 parseterminate("Unknown CTF version %d", h->cth_version); 1377 1378 ctfdatasz = h->cth_stroff + h->cth_strlen; 1379 if (h->cth_flags & CTF_F_COMPRESS) { 1380 size_t actual; 1381 1382 ctfdata = xmalloc(ctfdatasz); 1383 if ((actual = decompress_ctf(buf, bufsz, ctfdata, ctfdatasz)) != 1384 ctfdatasz) { 1385 parseterminate("Corrupt CTF - short decompression " 1386 "(was %zu, expecting %zu)", actual, ctfdatasz); 1387 } 1388 } else { 1389 ctfdata = buf; 1390 ctfdatasz = bufsz; 1391 } 1392 1393 td = ctf_parse(h, ctfdata, si, label); 1394 1395 if (h->cth_flags & CTF_F_COMPRESS) 1396 free(ctfdata); 1397 1398 curfile = NULL; 1399 1400 return (td); 1401 } 1402