Home | History | Annotate | Line # | Download | only in cvt
ctf.c revision 1.13
      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