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