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