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.
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.
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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Create and parse buffers containing CTF data.
30 #include <sys/types.h>
38 #include "ctf_headers.h"
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.
48 * The value is only valid during a call to ctf_load.
52 #define CTF_BUF_CHUNK_SIZE (64 * 1024)
53 #define RES_BUF_CHUNK_SIZE (64 * 1024)
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 */
67 parseterminate(char *fmt
, ...)
69 static char msgbuf
[1024]; /* sigh */
73 vsnprintf(msgbuf
, sizeof (msgbuf
), fmt
, ap
);
76 terminate("%s: %s\n", curfile
, msgbuf
);
80 ctf_buf_grow(ctf_buf_t
*b
)
82 off_t ptroff
= b
->ctb_ptr
- b
->ctb_base
;
84 b
->ctb_size
+= CTF_BUF_CHUNK_SIZE
;
85 b
->ctb_base
= xrealloc(b
->ctb_base
, b
->ctb_size
);
86 b
->ctb_end
= b
->ctb_base
+ b
->ctb_size
;
87 b
->ctb_ptr
= b
->ctb_base
+ ptroff
;
93 ctf_buf_t
*b
= xcalloc(sizeof (ctf_buf_t
));
95 strtab_create(&b
->ctb_strtab
);
102 ctf_buf_free(ctf_buf_t
*b
)
104 strtab_destroy(&b
->ctb_strtab
);
110 ctf_buf_cur(ctf_buf_t
*b
)
112 return (b
->ctb_ptr
- b
->ctb_base
);
116 ctf_buf_write(ctf_buf_t
*b
, const void *p
, size_t n
)
121 if (b
->ctb_ptr
== b
->ctb_end
)
124 len
= MIN((size_t)(b
->ctb_end
- b
->ctb_ptr
), n
);
125 bcopy(p
, b
->ctb_ptr
, len
);
134 write_label(labelent_t
*le
, ctf_buf_t
*b
)
138 ctl
.ctl_label
= strtab_insert(&b
->ctb_strtab
, le
->le_name
);
139 ctl
.ctl_typeidx
= le
->le_idx
;
141 ctf_buf_write(b
, &ctl
, sizeof (ctl
));
147 write_objects(iidesc_t
*idp
, ctf_buf_t
*b
)
149 ushort_t id
= (idp
? idp
->ii_dtype
->t_id
: 0);
151 ctf_buf_write(b
, &id
, sizeof (id
));
153 debug(3, "Wrote object %s (%d)\n", (idp
? idp
->ii_name
: "(null)"), id
);
157 write_functions(iidesc_t
*idp
, ctf_buf_t
*b
)
166 ctf_buf_write(b
, &fdata
[0], sizeof (fdata
[0]));
168 debug(3, "Wrote function (null)\n");
172 nargs
= idp
->ii_nargs
+ (idp
->ii_vargs
!= 0);
174 if (nargs
> CTF_MAX_VLEN
) {
175 terminate("function %s has too many args: %d > %d\n",
176 idp
->ii_name
, nargs
, CTF_MAX_VLEN
);
179 fdata
[0] = CTF_TYPE_INFO(CTF_K_FUNCTION
, 1, nargs
);
180 fdata
[1] = idp
->ii_dtype
->t_id
;
181 ctf_buf_write(b
, fdata
, sizeof (fdata
));
183 for (i
= 0; i
< idp
->ii_nargs
; i
++) {
184 id
= idp
->ii_args
[i
]->t_id
;
185 ctf_buf_write(b
, &id
, sizeof (id
));
190 ctf_buf_write(b
, &id
, sizeof (id
));
193 debug(3, "Wrote function %s (%d args)\n", idp
->ii_name
, nargs
);
197 * Depending on the size of the type being described, either a ctf_stype_t (for
198 * types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be
199 * written. We isolate the determination here so the rest of the writer code
200 * doesn't need to care.
203 write_sized_type_rec(ctf_buf_t
*b
, ctf_type_t
*ctt
, size_t size
)
205 if (size
> CTF_MAX_SIZE
) {
206 ctt
->ctt_size
= CTF_LSIZE_SENT
;
207 ctt
->ctt_lsizehi
= CTF_SIZE_TO_LSIZE_HI(size
);
208 ctt
->ctt_lsizelo
= CTF_SIZE_TO_LSIZE_LO(size
);
209 ctf_buf_write(b
, ctt
, sizeof (*ctt
));
211 ctf_stype_t
*cts
= (ctf_stype_t
*)ctt
;
213 cts
->ctt_size
= (ushort_t
)size
;
214 ctf_buf_write(b
, cts
, sizeof (*cts
));
219 write_unsized_type_rec(ctf_buf_t
*b
, ctf_type_t
*ctt
)
221 ctf_stype_t
*cts
= (ctf_stype_t
*)ctt
;
223 ctf_buf_write(b
, cts
, sizeof (*cts
));
227 write_type(tdesc_t
*tp
, ctf_buf_t
*b
)
236 int isroot
= tp
->t_flags
& TDESC_F_ISROOT
;
249 * There shouldn't be any holes in the type list (where a hole is
250 * defined as two consecutive tdescs without consecutive ids), but
251 * check for them just in case. If we do find holes, we need to make
252 * fake entries to fill the holes, or we won't be able to reconstruct
253 * the tree from the written data.
255 if (++b
->nptent
< CTF_TYPE_TO_INDEX(tp
->t_id
)) {
256 debug(2, "genctf: type hole from %d < x < %d\n",
257 b
->nptent
- 1, CTF_TYPE_TO_INDEX(tp
->t_id
));
259 ctt
.ctt_name
= CTF_TYPE_NAME(CTF_STRTAB_0
, 0);
260 ctt
.ctt_info
= CTF_TYPE_INFO(0, 0, 0);
261 while (b
->nptent
< CTF_TYPE_TO_INDEX(tp
->t_id
)) {
262 write_sized_type_rec(b
, &ctt
, 0);
267 offset
= strtab_insert(&b
->ctb_strtab
, tp
->t_name
);
268 ctt
.ctt_name
= CTF_TYPE_NAME(CTF_STRTAB_0
, offset
);
270 switch (tp
->t_type
) {
273 if (ip
->intr_type
== INTR_INT
)
274 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_INTEGER
,
277 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_FLOAT
, isroot
, 1);
278 write_sized_type_rec(b
, &ctt
, tp
->t_size
);
282 if (ip
->intr_type
== INTR_INT
) {
284 encoding
|= CTF_INT_SIGNED
;
285 if (ip
->intr_iformat
== 'c')
286 encoding
|= CTF_INT_CHAR
;
287 else if (ip
->intr_iformat
== 'b')
288 encoding
|= CTF_INT_BOOL
;
289 else if (ip
->intr_iformat
== 'v')
290 encoding
|= CTF_INT_VARARGS
;
292 encoding
= ip
->intr_fformat
;
294 data
= CTF_INT_DATA(encoding
, ip
->intr_offset
, ip
->intr_nbits
);
295 ctf_buf_write(b
, &data
, sizeof (data
));
299 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_POINTER
, isroot
, 0);
300 ctt
.ctt_type
= tp
->t_tdesc
->t_id
;
301 write_unsized_type_rec(b
, &ctt
);
305 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_ARRAY
, isroot
, 1);
306 write_sized_type_rec(b
, &ctt
, tp
->t_size
);
308 cta
.cta_contents
= tp
->t_ardef
->ad_contents
->t_id
;
309 cta
.cta_index
= tp
->t_ardef
->ad_idxtype
->t_id
;
310 cta
.cta_nelems
= tp
->t_ardef
->ad_nelems
;
311 ctf_buf_write(b
, &cta
, sizeof (cta
));
316 for (i
= 0, mp
= tp
->t_members
; mp
!= NULL
; mp
= mp
->ml_next
)
317 i
++; /* count up struct or union members */
319 if (i
> CTF_MAX_VLEN
) {
320 terminate("sou %s has too many members: %d > %d\n",
321 tdesc_name(tp
), i
, CTF_MAX_VLEN
);
324 if (tp
->t_type
== STRUCT
)
325 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_STRUCT
, isroot
, i
);
327 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_UNION
, isroot
, i
);
329 write_sized_type_rec(b
, &ctt
, tp
->t_size
);
331 if (tp
->t_size
< CTF_LSTRUCT_THRESH
) {
332 for (mp
= tp
->t_members
; mp
!= NULL
; mp
= mp
->ml_next
) {
333 offset
= strtab_insert(&b
->ctb_strtab
,
336 ctm
.ctm_name
= CTF_TYPE_NAME(CTF_STRTAB_0
,
338 ctm
.ctm_type
= mp
->ml_type
->t_id
;
339 ctm
.ctm_offset
= mp
->ml_offset
;
340 ctf_buf_write(b
, &ctm
, sizeof (ctm
));
343 for (mp
= tp
->t_members
; mp
!= NULL
; mp
= mp
->ml_next
) {
344 offset
= strtab_insert(&b
->ctb_strtab
,
347 ctlm
.ctlm_name
= CTF_TYPE_NAME(CTF_STRTAB_0
,
349 ctlm
.ctlm_type
= mp
->ml_type
->t_id
;
351 CTF_OFFSET_TO_LMEMHI(mp
->ml_offset
);
353 CTF_OFFSET_TO_LMEMLO(mp
->ml_offset
);
354 ctf_buf_write(b
, &ctlm
, sizeof (ctlm
));
360 for (i
= 0, ep
= tp
->t_emem
; ep
!= NULL
; ep
= ep
->el_next
)
361 i
++; /* count up enum members */
363 if (i
> CTF_MAX_VLEN
) {
364 terminate("enum %s has too many values: %d > %d\n",
365 tdesc_name(tp
), i
, CTF_MAX_VLEN
);
368 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_ENUM
, isroot
, i
);
369 write_sized_type_rec(b
, &ctt
, tp
->t_size
);
371 for (ep
= tp
->t_emem
; ep
!= NULL
; ep
= ep
->el_next
) {
372 offset
= strtab_insert(&b
->ctb_strtab
, ep
->el_name
);
373 cte
.cte_name
= CTF_TYPE_NAME(CTF_STRTAB_0
, offset
);
374 cte
.cte_value
= ep
->el_number
;
375 ctf_buf_write(b
, &cte
, sizeof (cte
));
380 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_FORWARD
, isroot
, 0);
382 write_unsized_type_rec(b
, &ctt
);
386 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_TYPEDEF
, isroot
, 0);
387 ctt
.ctt_type
= tp
->t_tdesc
->t_id
;
388 write_unsized_type_rec(b
, &ctt
);
392 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_VOLATILE
, isroot
, 0);
393 ctt
.ctt_type
= tp
->t_tdesc
->t_id
;
394 write_unsized_type_rec(b
, &ctt
);
398 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_CONST
, isroot
, 0);
399 ctt
.ctt_type
= tp
->t_tdesc
->t_id
;
400 write_unsized_type_rec(b
, &ctt
);
404 i
= tp
->t_fndef
->fn_nargs
+ tp
->t_fndef
->fn_vargs
;
406 if (i
> CTF_MAX_VLEN
) {
407 terminate("function %s has too many args: %d > %d\n",
411 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_FUNCTION
, isroot
, i
);
412 ctt
.ctt_type
= tp
->t_fndef
->fn_ret
->t_id
;
413 write_unsized_type_rec(b
, &ctt
);
415 for (i
= 0; i
< tp
->t_fndef
->fn_nargs
; i
++) {
416 id
= tp
->t_fndef
->fn_args
[i
]->t_id
;
417 ctf_buf_write(b
, &id
, sizeof (id
));
420 if (tp
->t_fndef
->fn_vargs
) {
422 ctf_buf_write(b
, &id
, sizeof (id
));
428 ctf_buf_write(b
, &id
, sizeof (id
));
433 ctt
.ctt_info
= CTF_TYPE_INFO(CTF_K_RESTRICT
, isroot
, 0);
434 ctt
.ctt_type
= tp
->t_tdesc
->t_id
;
435 write_unsized_type_rec(b
, &ctt
);
439 warning("Can't write unknown type %d\n", tp
->t_type
);
442 debug(3, "Wrote type %d %s\n", tp
->t_id
, tdesc_name(tp
));
447 typedef struct resbuf
{
455 rbzs_grow(resbuf_t
*rb
)
457 off_t ptroff
= (caddr_t
)rb
->rb_zstr
.next_out
- rb
->rb_base
;
459 rb
->rb_size
+= RES_BUF_CHUNK_SIZE
;
460 rb
->rb_base
= xrealloc(rb
->rb_base
, rb
->rb_size
);
461 rb
->rb_ptr
= rb
->rb_base
+ ptroff
;
462 rb
->rb_zstr
.next_out
= (Bytef
*)(rb
->rb_ptr
);
463 rb
->rb_zstr
.avail_out
+= RES_BUF_CHUNK_SIZE
;
467 compress_start(resbuf_t
*rb
)
471 rb
->rb_zstr
.zalloc
= (alloc_func
)0;
472 rb
->rb_zstr
.zfree
= (free_func
)0;
473 rb
->rb_zstr
.opaque
= (voidpf
)0;
475 if ((rc
= deflateInit(&rb
->rb_zstr
, Z_BEST_COMPRESSION
)) != Z_OK
)
476 parseterminate("zlib start failed: %s", zError(rc
));
480 compress_buffer(const void *buf
, size_t n
, void *data
)
482 resbuf_t
*rb
= (resbuf_t
*)data
;
485 rb
->rb_zstr
.next_out
= (Bytef
*)rb
->rb_ptr
;
486 rb
->rb_zstr
.avail_out
= rb
->rb_size
- (rb
->rb_ptr
- rb
->rb_base
);
487 rb
->rb_zstr
.next_in
= (Bytef
*)buf
;
488 rb
->rb_zstr
.avail_in
= n
;
490 while (rb
->rb_zstr
.avail_in
) {
491 if (rb
->rb_zstr
.avail_out
== 0)
494 if ((rc
= deflate(&rb
->rb_zstr
, Z_NO_FLUSH
)) != Z_OK
)
495 parseterminate("zlib deflate failed: %s", zError(rc
));
497 rb
->rb_ptr
= (caddr_t
)rb
->rb_zstr
.next_out
;
503 compress_flush(resbuf_t
*rb
, int type
)
508 if (rb
->rb_zstr
.avail_out
== 0)
511 rc
= deflate(&rb
->rb_zstr
, type
);
512 if ((type
== Z_FULL_FLUSH
&& rc
== Z_BUF_ERROR
) ||
513 (type
== Z_FINISH
&& rc
== Z_STREAM_END
))
516 parseterminate("zlib finish failed: %s", zError(rc
));
518 rb
->rb_ptr
= (caddr_t
)rb
->rb_zstr
.next_out
;
522 compress_end(resbuf_t
*rb
)
526 compress_flush(rb
, Z_FINISH
);
528 if ((rc
= deflateEnd(&rb
->rb_zstr
)) != Z_OK
)
529 parseterminate("zlib end failed: %s", zError(rc
));
533 * Pad the buffer to a power-of-2 boundary
536 pad_buffer(ctf_buf_t
*buf
, int align
)
538 uint_t cur
= ctf_buf_cur(buf
);
539 ssize_t topad
= (align
- (cur
% align
)) % align
;
540 static const char pad
[8] = { 0 };
543 ctf_buf_write(buf
, pad
, (topad
> 8 ? 8 : topad
));
549 bcopy_data(const void *buf
, size_t n
, void *data
)
551 caddr_t
*posp
= (caddr_t
*)data
;
552 bcopy(buf
, *posp
, n
);
558 write_buffer(ctf_header_t
*h
, ctf_buf_t
*buf
, size_t *resszp
)
563 outbuf
= xmalloc(sizeof (ctf_header_t
) + (buf
->ctb_ptr
- buf
->ctb_base
)
564 + buf
->ctb_strtab
.str_size
);
567 (void) bcopy_data(h
, sizeof (ctf_header_t
), &bufpos
);
568 (void) bcopy_data(buf
->ctb_base
, buf
->ctb_ptr
- buf
->ctb_base
,
570 (void) strtab_write(&buf
->ctb_strtab
, bcopy_data
, &bufpos
);
571 *resszp
= bufpos
- outbuf
;
576 * Create the compression buffer, and fill it with the CTF and string
577 * table data. We flush the compression state between the two so the
578 * dictionary used for the string tables won't be polluted with values
579 * that made sense for the CTF data.
582 write_compressed_buffer(ctf_header_t
*h
, ctf_buf_t
*buf
, size_t *resszp
)
585 resbuf
.rb_size
= RES_BUF_CHUNK_SIZE
;
586 resbuf
.rb_base
= xmalloc(resbuf
.rb_size
);
587 bcopy(h
, resbuf
.rb_base
, sizeof (ctf_header_t
));
588 resbuf
.rb_ptr
= resbuf
.rb_base
+ sizeof (ctf_header_t
);
590 compress_start(&resbuf
);
591 (void) compress_buffer(buf
->ctb_base
, buf
->ctb_ptr
- buf
->ctb_base
,
593 compress_flush(&resbuf
, Z_FULL_FLUSH
);
594 (void) strtab_write(&buf
->ctb_strtab
, compress_buffer
, &resbuf
);
595 compress_end(&resbuf
);
597 *resszp
= (resbuf
.rb_ptr
- resbuf
.rb_base
);
598 return (resbuf
.rb_base
);
602 ctf_gen(iiburst_t
*iiburst
, size_t *resszp
, int do_compress
)
604 ctf_buf_t
*buf
= ctf_buf_new();
611 * Prepare the header, and create the CTF output buffers. The data
612 * object section and function section are both lists of 2-byte
613 * integers; we pad these out to the next 4-byte boundary if needed.
615 h
.cth_magic
= CTF_MAGIC
;
616 h
.cth_version
= CTF_VERSION
;
617 h
.cth_flags
= do_compress
? CTF_F_COMPRESS
: 0;
618 h
.cth_parlabel
= strtab_insert(&buf
->ctb_strtab
,
619 iiburst
->iib_td
->td_parlabel
);
620 h
.cth_parname
= strtab_insert(&buf
->ctb_strtab
,
621 iiburst
->iib_td
->td_parname
);
624 (void) list_iter(iiburst
->iib_td
->td_labels
, (int (*)())write_label
,
628 h
.cth_objtoff
= ctf_buf_cur(buf
);
629 for (i
= 0; i
< iiburst
->iib_nobjts
; i
++)
630 write_objects(iiburst
->iib_objts
[i
], buf
);
633 h
.cth_funcoff
= ctf_buf_cur(buf
);
634 for (i
= 0; i
< iiburst
->iib_nfuncs
; i
++)
635 write_functions(iiburst
->iib_funcs
[i
], buf
);
638 h
.cth_typeoff
= ctf_buf_cur(buf
);
639 (void) list_iter(iiburst
->iib_types
, (int (*)())write_type
, buf
);
641 debug(2, "CTF wrote %d types\n", list_count(iiburst
->iib_types
));
643 h
.cth_stroff
= ctf_buf_cur(buf
);
644 h
.cth_strlen
= strtab_size(&buf
->ctb_strtab
);
647 * We only do compression for ctfmerge, as ctfconvert is only
648 * supposed to be used on intermediary build objects. This is
649 * significantly faster.
652 outbuf
= write_compressed_buffer(&h
, buf
, resszp
);
654 outbuf
= write_buffer(&h
, buf
, resszp
);
661 get_ctt_size(ctf_type_t
*ctt
, size_t *sizep
, size_t *incrementp
)
663 if (ctt
->ctt_size
== CTF_LSIZE_SENT
) {
664 *sizep
= (size_t)CTF_TYPE_LSIZE(ctt
);
665 *incrementp
= sizeof (ctf_type_t
);
667 *sizep
= ctt
->ctt_size
;
668 *incrementp
= sizeof (ctf_stype_t
);
673 count_types(ctf_header_t
*h
, caddr_t data
)
675 caddr_t dptr
= data
+ h
->cth_typeoff
;
678 dptr
= data
+ h
->cth_typeoff
;
679 while (dptr
< data
+ h
->cth_stroff
) {
680 /* LINTED - pointer alignment */
681 ctf_type_t
*ctt
= (ctf_type_t
*)dptr
;
682 size_t vlen
= CTF_INFO_VLEN(ctt
->ctt_info
);
683 size_t size
, increment
;
685 get_ctt_size(ctt
, &size
, &increment
);
687 switch (CTF_INFO_KIND(ctt
->ctt_info
)) {
699 dptr
+= sizeof (ushort_t
) * (vlen
+ (vlen
& 1));
702 dptr
+= sizeof (ctf_array_t
);
706 if (size
< CTF_LSTRUCT_THRESH
)
707 dptr
+= sizeof (ctf_member_t
) * vlen
;
709 dptr
+= sizeof (ctf_lmember_t
) * vlen
;
712 dptr
+= sizeof (ctf_enum_t
) * vlen
;
717 parseterminate("Unknown CTF type %d (#%d) at %#x",
718 CTF_INFO_KIND(ctt
->ctt_info
), count
, dptr
- data
);
725 debug(3, "CTF read %d types\n", count
);
731 * Resurrect the labels stored in the CTF data, returning the index associated
732 * with a label provided by the caller. There are several cases, outlined
733 * below. Note that, given two labels, the one associated with the lesser type
734 * index is considered to be older than the other.
736 * 1. matchlbl == NULL - return the index of the most recent label.
737 * 2. matchlbl == "BASE" - return the index of the oldest label.
738 * 3. matchlbl != NULL, but doesn't match any labels in the section - warn
739 * the user, and proceed as if matchlbl == "BASE" (for safety).
740 * 4. matchlbl != NULL, and matches one of the labels in the section - return
741 * the type index associated with the label.
744 resurrect_labels(ctf_header_t
*h
, tdata_t
*td
, caddr_t ctfdata
, char *matchlbl
)
746 caddr_t buf
= ctfdata
+ h
->cth_lbloff
;
747 caddr_t sbuf
= ctfdata
+ h
->cth_stroff
;
748 size_t bufsz
= h
->cth_objtoff
- h
->cth_lbloff
;
749 int lastidx
= 0, baseidx
= -1;
753 /* LINTED - pointer alignment */
754 for (ctl
= (ctf_lblent_t
*)buf
; (caddr_t
)ctl
< buf
+ bufsz
; ctl
++) {
755 char *label
= sbuf
+ ctl
->ctl_label
;
757 lastidx
= ctl
->ctl_typeidx
;
759 debug(3, "Resurrected label %s type idx %d\n", label
, lastidx
);
761 tdata_label_add(td
, label
, lastidx
);
766 if (matchlbl
!= NULL
&& streq(matchlbl
, "BASE"))
770 if (matchlbl
!= NULL
&& streq(label
, matchlbl
))
774 if (matchlbl
!= NULL
) {
775 /* User provided a label that didn't match */
776 warning("%s: Cannot find label `%s' - using base (%s)\n",
777 curfile
, matchlbl
, (baselabel
? baselabel
: "NONE"));
779 tdata_label_free(td
);
780 tdata_label_add(td
, baselabel
, baseidx
);
789 resurrect_objects(ctf_header_t
*h
, tdata_t
*td
, tdesc_t
**tdarr
, int tdsize
,
790 caddr_t ctfdata
, symit_data_t
*si
)
792 caddr_t buf
= ctfdata
+ h
->cth_objtoff
;
793 size_t bufsz
= h
->cth_funcoff
- h
->cth_objtoff
;
797 for (dptr
= buf
; dptr
< buf
+ bufsz
; dptr
+= 2) {
798 /* LINTED - pointer alignment */
799 ushort_t id
= *((ushort_t
*)dptr
);
803 if (!(sym
= symit_next(si
, STT_OBJECT
)) && id
!= 0) {
805 "Unexpected end of object symbols at %x of %x",
810 debug(3, "Skipping null object\n");
812 } else if (id
>= tdsize
) {
813 parseterminate("Reference to invalid type %d", id
);
816 ii
= iidesc_new(symit_name(si
));
817 ii
->ii_dtype
= tdarr
[id
];
818 if (GELF_ST_BIND(sym
->st_info
) == STB_LOCAL
) {
819 ii
->ii_type
= II_SVAR
;
820 ii
->ii_owner
= xstrdup(symit_curfile(si
));
822 ii
->ii_type
= II_GVAR
;
823 hash_add(td
->td_iihash
, ii
);
825 debug(3, "Resurrected %s object %s (%d) from %s\n",
826 (ii
->ii_type
== II_GVAR
? "global" : "static"),
827 ii
->ii_name
, id
, (ii
->ii_owner
? ii
->ii_owner
: "(none)"));
832 resurrect_functions(ctf_header_t
*h
, tdata_t
*td
, tdesc_t
**tdarr
, int tdsize
,
833 caddr_t ctfdata
, symit_data_t
*si
)
835 caddr_t buf
= ctfdata
+ h
->cth_funcoff
;
836 size_t bufsz
= h
->cth_typeoff
- h
->cth_funcoff
;
845 while (dptr
< buf
+ bufsz
) {
846 /* LINTED - pointer alignment */
847 info
= *((ushort_t
*)dptr
);
850 if (!(sym
= symit_next(si
, STT_FUNC
)) && info
!= 0)
851 parseterminate("Unexpected end of function symbols");
854 debug(3, "Skipping null function (%s)\n",
859 /* LINTED - pointer alignment */
860 retid
= *((ushort_t
*)dptr
);
864 parseterminate("Reference to invalid type %d", retid
);
866 ii
= iidesc_new(symit_name(si
));
867 ii
->ii_dtype
= tdarr
[retid
];
868 if (GELF_ST_BIND(sym
->st_info
) == STB_LOCAL
) {
869 ii
->ii_type
= II_SFUN
;
870 ii
->ii_owner
= xstrdup(symit_curfile(si
));
872 ii
->ii_type
= II_GFUN
;
873 ii
->ii_nargs
= CTF_INFO_VLEN(info
);
876 xmalloc(sizeof (tdesc_t
*) * ii
->ii_nargs
);
878 for (i
= 0; i
< ii
->ii_nargs
; i
++, dptr
+= 2) {
879 /* LINTED - pointer alignment */
880 ushort_t id
= *((ushort_t
*)dptr
);
882 parseterminate("Reference to invalid type %d",
884 ii
->ii_args
[i
] = tdarr
[id
];
887 if (ii
->ii_nargs
&& ii
->ii_args
[ii
->ii_nargs
- 1] == NULL
) {
892 hash_add(td
->td_iihash
, ii
);
894 debug(3, "Resurrected %s function %s (%d, %d args)\n",
895 (ii
->ii_type
== II_GFUN
? "global" : "static"),
896 ii
->ii_name
, retid
, ii
->ii_nargs
);
901 resurrect_types(ctf_header_t
*h
, tdata_t
*td
, tdesc_t
**tdarr
, int tdsize
,
902 caddr_t ctfdata
, int maxid
)
904 caddr_t buf
= ctfdata
+ h
->cth_typeoff
;
905 size_t bufsz
= h
->cth_stroff
- h
->cth_typeoff
;
906 caddr_t sbuf
= ctfdata
+ h
->cth_stroff
;
911 size_t size
, increment
;
927 * A maxid of zero indicates a request to resurrect all types, so reset
928 * maxid to the maximum type id.
931 maxid
= CTF_MAX_TYPE
;
933 for (dptr
= buf
, tcnt
= 0, tid
= 1; dptr
< buf
+ bufsz
; tcnt
++, tid
++) {
938 parseterminate("Reference to invalid type %d", tid
);
940 /* LINTED - pointer alignment */
941 ctt
= (ctf_type_t
*)dptr
;
943 get_ctt_size(ctt
, &size
, &increment
);
948 if (CTF_NAME_STID(ctt
->ctt_name
) != CTF_STRTAB_0
)
950 "Unable to cope with non-zero strtab id");
951 if (CTF_NAME_OFFSET(ctt
->ctt_name
) != 0) {
953 xstrdup(sbuf
+ CTF_NAME_OFFSET(ctt
->ctt_name
));
957 kind
= CTF_INFO_KIND(ctt
->ctt_info
);
958 vlen
= CTF_INFO_VLEN(ctt
->ctt_info
);
962 tdp
->t_type
= INTRINSIC
;
965 /* LINTED - pointer alignment */
966 data
= *((uint_t
*)dptr
);
967 dptr
+= sizeof (uint_t
);
968 encoding
= CTF_INT_ENCODING(data
);
970 ip
= xmalloc(sizeof (intr_t
));
971 ip
->intr_type
= INTR_INT
;
972 ip
->intr_signed
= (encoding
& CTF_INT_SIGNED
) ? 1 : 0;
974 if (encoding
& CTF_INT_CHAR
)
975 ip
->intr_iformat
= 'c';
976 else if (encoding
& CTF_INT_BOOL
)
977 ip
->intr_iformat
= 'b';
978 else if (encoding
& CTF_INT_VARARGS
)
979 ip
->intr_iformat
= 'v';
981 ip
->intr_iformat
= '\0';
983 ip
->intr_offset
= CTF_INT_OFFSET(data
);
984 ip
->intr_nbits
= CTF_INT_BITS(data
);
989 tdp
->t_type
= INTRINSIC
;
992 /* LINTED - pointer alignment */
993 data
= *((uint_t
*)dptr
);
994 dptr
+= sizeof (uint_t
);
996 ip
= xcalloc(sizeof (intr_t
));
997 ip
->intr_type
= INTR_REAL
;
998 ip
->intr_fformat
= CTF_FP_ENCODING(data
);
999 ip
->intr_offset
= CTF_FP_OFFSET(data
);
1000 ip
->intr_nbits
= CTF_FP_BITS(data
);
1005 tdp
->t_type
= POINTER
;
1006 tdp
->t_tdesc
= tdarr
[ctt
->ctt_type
];
1010 tdp
->t_type
= ARRAY
;
1013 /* LINTED - pointer alignment */
1014 cta
= (ctf_array_t
*)dptr
;
1015 dptr
+= sizeof (ctf_array_t
);
1017 tdp
->t_ardef
= xmalloc(sizeof (ardef_t
));
1018 tdp
->t_ardef
->ad_contents
= tdarr
[cta
->cta_contents
];
1019 tdp
->t_ardef
->ad_idxtype
= tdarr
[cta
->cta_index
];
1020 tdp
->t_ardef
->ad_nelems
= cta
->cta_nelems
;
1025 tdp
->t_type
= (kind
== CTF_K_STRUCT
? STRUCT
: UNION
);
1028 if (size
< CTF_LSTRUCT_THRESH
) {
1029 for (i
= 0, mpp
= &tdp
->t_members
; i
< vlen
;
1030 i
++, mpp
= &((*mpp
)->ml_next
)) {
1031 /* LINTED - pointer alignment */
1032 ctf_member_t
*ctm
= (ctf_member_t
*)
1034 dptr
+= sizeof (ctf_member_t
);
1036 *mpp
= xmalloc(sizeof (mlist_t
));
1037 (*mpp
)->ml_name
= xstrdup(sbuf
+
1039 (*mpp
)->ml_type
= tdarr
[ctm
->ctm_type
];
1040 (*mpp
)->ml_offset
= ctm
->ctm_offset
;
1041 (*mpp
)->ml_size
= 0;
1044 for (i
= 0, mpp
= &tdp
->t_members
; i
< vlen
;
1045 i
++, mpp
= &((*mpp
)->ml_next
)) {
1046 /* LINTED - pointer alignment */
1047 ctf_lmember_t
*ctlm
= (ctf_lmember_t
*)
1049 dptr
+= sizeof (ctf_lmember_t
);
1051 *mpp
= xmalloc(sizeof (mlist_t
));
1052 (*mpp
)->ml_name
= xstrdup(sbuf
+
1055 tdarr
[ctlm
->ctlm_type
];
1057 (int)CTF_LMEM_OFFSET(ctlm
);
1058 (*mpp
)->ml_size
= 0;
1069 for (i
= 0, epp
= &tdp
->t_emem
; i
< vlen
;
1070 i
++, epp
= &((*epp
)->el_next
)) {
1071 /* LINTED - pointer alignment */
1072 cte
= (ctf_enum_t
*)dptr
;
1073 dptr
+= sizeof (ctf_enum_t
);
1075 *epp
= xmalloc(sizeof (elist_t
));
1076 (*epp
)->el_name
= xstrdup(sbuf
+ cte
->cte_name
);
1077 (*epp
)->el_number
= cte
->cte_value
;
1083 tdp
->t_type
= FORWARD
;
1084 list_add(&td
->td_fwdlist
, tdp
);
1088 tdp
->t_type
= TYPEDEF
;
1089 tdp
->t_tdesc
= tdarr
[ctt
->ctt_type
];
1092 case CTF_K_VOLATILE
:
1093 tdp
->t_type
= VOLATILE
;
1094 tdp
->t_tdesc
= tdarr
[ctt
->ctt_type
];
1098 tdp
->t_type
= CONST
;
1099 tdp
->t_tdesc
= tdarr
[ctt
->ctt_type
];
1102 case CTF_K_FUNCTION
:
1103 tdp
->t_type
= FUNCTION
;
1104 tdp
->t_fndef
= xcalloc(sizeof (fndef_t
));
1105 tdp
->t_fndef
->fn_ret
= tdarr
[ctt
->ctt_type
];
1107 /* LINTED - pointer alignment */
1108 if (vlen
> 0 && *(ushort_t
*)(dptr
+
1109 (sizeof (ushort_t
) * (vlen
- 1))) == 0)
1110 tdp
->t_fndef
->fn_vargs
= 1;
1112 tdp
->t_fndef
->fn_nargs
= vlen
- tdp
->t_fndef
->fn_vargs
;
1113 tdp
->t_fndef
->fn_args
= xcalloc(sizeof (tdesc_t
) *
1114 vlen
- tdp
->t_fndef
->fn_vargs
);
1116 for (i
= 0; i
< vlen
; i
++) {
1117 /* LINTED - pointer alignment */
1118 argid
= *(ushort_t
*)dptr
;
1119 dptr
+= sizeof (ushort_t
);
1122 tdp
->t_fndef
->fn_args
[i
] = tdarr
[argid
];
1126 dptr
+= sizeof (ushort_t
);
1129 case CTF_K_RESTRICT
:
1130 tdp
->t_type
= RESTRICT
;
1131 tdp
->t_tdesc
= tdarr
[ctt
->ctt_type
];
1138 warning("Can't parse unknown CTF type %d\n", kind
);
1141 if (CTF_INFO_ISROOT(ctt
->ctt_info
)) {
1142 iidesc_t
*ii
= iidesc_new(tdp
->t_name
);
1143 if (tdp
->t_type
== STRUCT
|| tdp
->t_type
== UNION
||
1144 tdp
->t_type
== ENUM
)
1145 ii
->ii_type
= II_SOU
;
1147 ii
->ii_type
= II_TYPE
;
1149 hash_add(td
->td_iihash
, ii
);
1154 debug(3, "Resurrected %d %stype %s (%d)\n", tdp
->t_type
,
1155 (CTF_INFO_ISROOT(ctt
->ctt_info
) ? "root " : ""),
1156 tdesc_name(tdp
), tdp
->t_id
);
1159 debug(3, "Resurrected %d types (%d were roots)\n", tcnt
, iicnt
);
1163 * For lack of other inspiration, we're going to take the boring route. We
1164 * count the number of types. This lets us malloc that many tdesc structs
1165 * before we start filling them in. This has the advantage of allowing us to
1166 * avoid a merge-esque remap step.
1169 ctf_parse(ctf_header_t
*h
, caddr_t buf
, symit_data_t
*si
, char *label
)
1171 tdata_t
*td
= tdata_new();
1173 int ntypes
= count_types(h
, buf
);
1177 tdarr
= xcalloc(sizeof (tdesc_t
*) * (ntypes
+ 1));
1179 for (i
= 1; i
<= ntypes
; i
++) {
1180 tdarr
[i
] = xcalloc(sizeof (tdesc_t
));
1184 td
->td_parlabel
= xstrdup(buf
+ h
->cth_stroff
+ h
->cth_parlabel
);
1186 /* we have the technology - we can rebuild them */
1187 idx
= resurrect_labels(h
, td
, buf
, label
);
1189 resurrect_objects(h
, td
, tdarr
, ntypes
+ 1, buf
, si
);
1190 resurrect_functions(h
, td
, tdarr
, ntypes
+ 1, buf
, si
);
1191 resurrect_types(h
, td
, tdarr
, ntypes
+ 1, buf
, idx
);
1195 td
->td_nextid
= ntypes
+ 1;
1201 decompress_ctf(caddr_t cbuf
, size_t cbufsz
, caddr_t dbuf
, size_t dbufsz
)
1206 zstr
.zalloc
= (alloc_func
)0;
1207 zstr
.zfree
= (free_func
)0;
1208 zstr
.opaque
= (voidpf
)0;
1210 zstr
.next_in
= (Bytef
*)cbuf
;
1211 zstr
.avail_in
= cbufsz
;
1212 zstr
.next_out
= (Bytef
*)dbuf
;
1213 zstr
.avail_out
= dbufsz
;
1215 if ((rc
= inflateInit(&zstr
)) != Z_OK
||
1216 (rc
= inflate(&zstr
, Z_NO_FLUSH
)) != Z_STREAM_END
||
1217 (rc
= inflateEnd(&zstr
)) != Z_OK
) {
1218 warning("CTF decompress zlib error %s\n", zError(rc
));
1222 debug(3, "reflated %lu bytes to %lu, pointer at %d\n",
1223 zstr
.total_in
, zstr
.total_out
, (caddr_t
)zstr
.next_in
- cbuf
);
1225 return (zstr
.total_out
);
1229 * Reconstruct the type tree from a given buffer of CTF data. Only the types
1230 * up to the type associated with the provided label, inclusive, will be
1231 * reconstructed. If a NULL label is provided, all types will be reconstructed.
1233 * This function won't work on files that have been uniquified.
1236 ctf_load(char *file
, caddr_t buf
, size_t bufsz
, symit_data_t
*si
, char *label
)
1245 if (bufsz
< sizeof (ctf_header_t
))
1246 parseterminate("Corrupt CTF - short header");
1248 /* LINTED - pointer alignment */
1249 h
= (ctf_header_t
*)buf
;
1250 buf
+= sizeof (ctf_header_t
);
1251 bufsz
-= sizeof (ctf_header_t
);
1253 if (h
->cth_magic
!= CTF_MAGIC
)
1254 parseterminate("Corrupt CTF - bad magic 0x%x", h
->cth_magic
);
1256 if (h
->cth_version
!= CTF_VERSION
)
1257 parseterminate("Unknown CTF version %d", h
->cth_version
);
1259 ctfdatasz
= h
->cth_stroff
+ h
->cth_strlen
;
1260 if (h
->cth_flags
& CTF_F_COMPRESS
) {
1263 ctfdata
= xmalloc(ctfdatasz
);
1264 if ((actual
= decompress_ctf(buf
, bufsz
, ctfdata
, ctfdatasz
)) !=
1266 parseterminate("Corrupt CTF - short decompression "
1267 "(was %d, expecting %d)", actual
, ctfdatasz
);
1274 td
= ctf_parse(h
, ctfdata
, si
, label
);
1276 if (h
->cth_flags
& CTF_F_COMPRESS
)