diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c index 5cd2de9f43ea..b3b4c1f7168f 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c @@ -58,8 +58,7 @@ struct ctf_buf { caddr_t ctb_end; /* pointer to end of buffer */ caddr_t ctb_ptr; /* pointer to empty buffer space */ size_t ctb_size; /* size of buffer */ - int nptent; /* number of processed types */ - int ntholes; /* number of type holes */ + uint_t nptent; /* number of processed types */ }; /* @@ -165,10 +164,10 @@ write_label(void *arg1, void *arg2) static void write_objects(iidesc_t *idp, ctf_buf_t *b) { - ushort_t id = (idp ? idp->ii_dtype->t_id : 0); + uint_t id = (idp ? idp->ii_dtype->t_id : 0); if (target_requires_swap) { - SWAP_16(id); + SWAP_32(id); } ctf_buf_write(b, &id, sizeof (id)); @@ -179,8 +178,8 @@ write_objects(iidesc_t *idp, ctf_buf_t *b) static void write_functions(iidesc_t *idp, ctf_buf_t *b) { - ushort_t fdata[2]; - ushort_t id; + uint_t fdata[2]; + uint_t id; int nargs; int i; @@ -194,17 +193,17 @@ write_functions(iidesc_t *idp, ctf_buf_t *b) nargs = idp->ii_nargs + (idp->ii_vargs != 0); - if (nargs > CTF_MAX_VLEN) { + if (nargs > CTF_V3_MAX_VLEN) { terminate("function %s has too many args: %d > %d\n", - idp->ii_name, nargs, CTF_MAX_VLEN); + idp->ii_name, nargs, CTF_V3_MAX_VLEN); } - fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); + fdata[0] = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, 1, nargs); fdata[1] = idp->ii_dtype->t_id; if (target_requires_swap) { - SWAP_16(fdata[0]); - SWAP_16(fdata[1]); + SWAP_32(fdata[0]); + SWAP_32(fdata[1]); } ctf_buf_write(b, fdata, sizeof (fdata)); @@ -213,7 +212,7 @@ write_functions(iidesc_t *idp, ctf_buf_t *b) id = idp->ii_args[i]->t_id; if (target_requires_swap) { - SWAP_16(id); + SWAP_32(id); } ctf_buf_write(b, &id, sizeof (id)); @@ -234,29 +233,29 @@ write_functions(iidesc_t *idp, ctf_buf_t *b) * doesn't need to care. */ static void -write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size) +write_sized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt, size_t size) { - if (size > CTF_MAX_SIZE) { - ctt->ctt_size = CTF_LSIZE_SENT; + if (size > CTF_V3_MAX_SIZE) { + ctt->ctt_size = CTF_V3_LSIZE_SENT; ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size); ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size); if (target_requires_swap) { SWAP_32(ctt->ctt_name); - SWAP_16(ctt->ctt_info); - SWAP_16(ctt->ctt_size); + SWAP_32(ctt->ctt_info); + SWAP_32(ctt->ctt_size); SWAP_32(ctt->ctt_lsizehi); SWAP_32(ctt->ctt_lsizelo); } ctf_buf_write(b, ctt, sizeof (*ctt)); } else { - ctf_stype_t *cts = (ctf_stype_t *)ctt; + struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; - cts->ctt_size = (ushort_t)size; + cts->ctt_size = size; if (target_requires_swap) { SWAP_32(cts->ctt_name); - SWAP_16(cts->ctt_info); - SWAP_16(cts->ctt_size); + SWAP_32(cts->ctt_info); + SWAP_32(cts->ctt_size); } ctf_buf_write(b, cts, sizeof (*cts)); @@ -264,14 +263,14 @@ write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size) } static void -write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt) +write_unsized_type_rec(ctf_buf_t *b, struct ctf_type_v3 *ctt) { - ctf_stype_t *cts = (ctf_stype_t *)ctt; + struct ctf_stype_v3 *cts = (struct ctf_stype_v3 *)ctt; if (target_requires_swap) { SWAP_32(cts->ctt_name); - SWAP_16(cts->ctt_info); - SWAP_16(cts->ctt_size); + SWAP_32(cts->ctt_info); + SWAP_32(cts->ctt_size); } ctf_buf_write(b, cts, sizeof (*cts)); @@ -292,14 +291,12 @@ write_type(void *arg1, void *arg2) int isroot = tp->t_flags & TDESC_F_ISROOT; int i; - ctf_type_t ctt; - ctf_array_t cta; - ctf_member_t ctm; - ctf_lmember_t ctlm; - ctf_enum_t cte; - ushort_t id; - - ctlm.ctlm_pad = 0; + struct ctf_type_v3 ctt; + struct ctf_array_v3 cta; + struct ctf_member_v3 ctm; + struct ctf_lmember_v3 ctlm; + struct ctf_enum cte; + uint_t id; /* * There shouldn't be any holes in the type list (where a hole is @@ -308,13 +305,13 @@ write_type(void *arg1, void *arg2) * fake entries to fill the holes, or we won't be able to reconstruct * the tree from the written data. */ - if (++b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) { + if (++b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { debug(2, "genctf: type hole from %d < x < %d\n", - b->nptent - 1, CTF_TYPE_TO_INDEX(tp->t_id)); + b->nptent - 1, CTF_V3_TYPE_TO_INDEX(tp->t_id)); ctt.ctt_name = CTF_TYPE_NAME(CTF_STRTAB_0, 0); - ctt.ctt_info = CTF_TYPE_INFO(0, 0, 0); - while (b->nptent < CTF_TYPE_TO_INDEX(tp->t_id)) { + ctt.ctt_info = CTF_V3_TYPE_INFO(0, 0, 0); + while (b->nptent < CTF_V3_TYPE_TO_INDEX(tp->t_id)) { write_sized_type_rec(b, &ctt, 0); b->nptent++; } @@ -327,10 +324,10 @@ write_type(void *arg1, void *arg2) case INTRINSIC: ip = tp->t_intr; if (ip->intr_type == INTR_INT) - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_INTEGER, + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_INTEGER, isroot, 1); else - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FLOAT, isroot, 1); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FLOAT, isroot, 1); write_sized_type_rec(b, &ctt, tp->t_size); encoding = 0; @@ -355,21 +352,21 @@ write_type(void *arg1, void *arg2) break; case POINTER: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_POINTER, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_POINTER, isroot, 0); ctt.ctt_type = tp->t_tdesc->t_id; write_unsized_type_rec(b, &ctt); break; case ARRAY: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, isroot, 1); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ARRAY, isroot, 1); write_sized_type_rec(b, &ctt, tp->t_size); cta.cta_contents = tp->t_ardef->ad_contents->t_id; cta.cta_index = tp->t_ardef->ad_idxtype->t_id; cta.cta_nelems = tp->t_ardef->ad_nelems; if (target_requires_swap) { - SWAP_16(cta.cta_contents); - SWAP_16(cta.cta_index); + SWAP_32(cta.cta_contents); + SWAP_32(cta.cta_index); SWAP_32(cta.cta_nelems); } ctf_buf_write(b, &cta, sizeof (cta)); @@ -380,19 +377,19 @@ write_type(void *arg1, void *arg2) for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) i++; /* count up struct or union members */ - if (i > CTF_MAX_VLEN) { + if (i > CTF_V3_MAX_VLEN) { terminate("sou %s has too many members: %d > %d\n", - tdesc_name(tp), i, CTF_MAX_VLEN); + tdesc_name(tp), i, CTF_V3_MAX_VLEN); } if (tp->t_type == STRUCT) - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_STRUCT, isroot, i); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_STRUCT, isroot, i); else - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_UNION, isroot, i); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_UNION, isroot, i); write_sized_type_rec(b, &ctt, tp->t_size); - if (tp->t_size < CTF_LSTRUCT_THRESH) { + if (tp->t_size < CTF_V3_LSTRUCT_THRESH) { for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { offset = strtab_insert(&b->ctb_strtab, mp->ml_name); @@ -403,8 +400,8 @@ write_type(void *arg1, void *arg2) ctm.ctm_offset = mp->ml_offset; if (target_requires_swap) { SWAP_32(ctm.ctm_name); - SWAP_16(ctm.ctm_type); - SWAP_16(ctm.ctm_offset); + SWAP_32(ctm.ctm_type); + SWAP_32(ctm.ctm_offset); } ctf_buf_write(b, &ctm, sizeof (ctm)); } @@ -423,7 +420,7 @@ write_type(void *arg1, void *arg2) if (target_requires_swap) { SWAP_32(ctlm.ctlm_name); - SWAP_16(ctlm.ctlm_type); + SWAP_32(ctlm.ctlm_type); SWAP_32(ctlm.ctlm_offsethi); SWAP_32(ctlm.ctlm_offsetlo); } @@ -437,11 +434,11 @@ write_type(void *arg1, void *arg2) for (i = 0, ep = tp->t_emem; ep != NULL; ep = ep->el_next) i++; /* count up enum members */ - if (i > CTF_MAX_VLEN) { - i = CTF_MAX_VLEN; + if (i > CTF_V3_MAX_VLEN) { + i = CTF_V3_MAX_VLEN; } - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_ENUM, isroot, i); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_ENUM, isroot, i); write_sized_type_rec(b, &ctt, tp->t_size); for (ep = tp->t_emem; ep != NULL && i > 0; ep = ep->el_next) { @@ -460,25 +457,25 @@ write_type(void *arg1, void *arg2) break; case FORWARD: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FORWARD, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FORWARD, isroot, 0); ctt.ctt_type = 0; write_unsized_type_rec(b, &ctt); break; case TYPEDEF: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_TYPEDEF, isroot, 0); ctt.ctt_type = tp->t_tdesc->t_id; write_unsized_type_rec(b, &ctt); break; case VOLATILE: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_VOLATILE, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_VOLATILE, isroot, 0); ctt.ctt_type = tp->t_tdesc->t_id; write_unsized_type_rec(b, &ctt); break; case CONST: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_CONST, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_CONST, isroot, 0); ctt.ctt_type = tp->t_tdesc->t_id; write_unsized_type_rec(b, &ctt); break; @@ -486,12 +483,12 @@ write_type(void *arg1, void *arg2) case FUNCTION: i = tp->t_fndef->fn_nargs + tp->t_fndef->fn_vargs; - if (i > CTF_MAX_VLEN) { + if (i > CTF_V3_MAX_VLEN) { terminate("function %s has too many args: %d > %d\n", - tdesc_name(tp), i, CTF_MAX_VLEN); + tdesc_name(tp), i, CTF_V3_MAX_VLEN); } - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, isroot, i); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_FUNCTION, isroot, i); ctt.ctt_type = tp->t_fndef->fn_ret->t_id; write_unsized_type_rec(b, &ctt); @@ -499,7 +496,7 @@ write_type(void *arg1, void *arg2) id = tp->t_fndef->fn_args[i]->t_id; if (target_requires_swap) { - SWAP_16(id); + SWAP_32(id); } ctf_buf_write(b, &id, sizeof (id)); @@ -511,14 +508,10 @@ write_type(void *arg1, void *arg2) i++; } - if (i & 1) { - id = 0; - ctf_buf_write(b, &id, sizeof (id)); - } break; case RESTRICT: - ctt.ctt_info = CTF_TYPE_INFO(CTF_K_RESTRICT, isroot, 0); + ctt.ctt_info = CTF_V3_TYPE_INFO(CTF_K_RESTRICT, isroot, 0); ctt.ctt_type = tp->t_tdesc->t_id; write_unsized_type_rec(b, &ctt); break; @@ -704,7 +697,7 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) * integers; we pad these out to the next 4-byte boundary if needed. */ h.cth_magic = CTF_MAGIC; - h.cth_version = CTF_VERSION; + h.cth_version = CTF_VERSION_3; h.cth_flags = do_compress ? CTF_F_COMPRESS : 0; h.cth_parlabel = strtab_insert(&buf->ctb_strtab, iiburst->iib_td->td_parlabel); @@ -761,14 +754,46 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress) } static void -get_ctt_size(ctf_type_t *ctt, size_t *sizep, size_t *incrementp) +get_ctt_info(ctf_header_t *h, void *v, uint_t *kind, uint_t *vlen, int *isroot) { - if (ctt->ctt_size == CTF_LSIZE_SENT) { - *sizep = (size_t)CTF_TYPE_LSIZE(ctt); - *incrementp = sizeof (ctf_type_t); + if (h->cth_version == CTF_VERSION_2) { + struct ctf_type_v2 *ctt = v; + + *kind = CTF_V2_INFO_KIND(ctt->ctt_info); + *vlen = CTF_V2_INFO_VLEN(ctt->ctt_info); + *isroot = CTF_V2_INFO_ISROOT(ctt->ctt_info); } else { - *sizep = ctt->ctt_size; - *incrementp = sizeof (ctf_stype_t); + struct ctf_type_v3 *ctt = v; + + *kind = CTF_V3_INFO_KIND(ctt->ctt_info); + *vlen = CTF_V3_INFO_VLEN(ctt->ctt_info); + *isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info); + } +} + +static void +get_ctt_size(ctf_header_t *h, void *v, size_t *sizep, size_t *incrementp) +{ + if (h->cth_version == CTF_VERSION_2) { + struct ctf_type_v2 *ctt = v; + + if (ctt->ctt_size == CTF_V2_LSIZE_SENT) { + *sizep = (size_t)CTF_TYPE_LSIZE(ctt); + *incrementp = sizeof (struct ctf_type_v2); + } else { + *sizep = ctt->ctt_size; + *incrementp = sizeof (struct ctf_stype_v2); + } + } else { + struct ctf_type_v3 *ctt = v; + + if (ctt->ctt_size == CTF_V3_LSIZE_SENT) { + *sizep = (size_t)CTF_TYPE_LSIZE(ctt); + *incrementp = sizeof (struct ctf_type_v3); + } else { + *sizep = ctt->ctt_size; + *incrementp = sizeof (struct ctf_stype_v3); + } } } @@ -776,18 +801,22 @@ static int count_types(ctf_header_t *h, caddr_t data) { caddr_t dptr = data + h->cth_typeoff; + uint_t version = h->cth_version; + size_t idwidth; int count = 0; + idwidth = version == CTF_VERSION_2 ? 2 : 4; dptr = data + h->cth_typeoff; while (dptr < data + h->cth_stroff) { void *v = (void *) dptr; - ctf_type_t *ctt = v; - size_t vlen = CTF_INFO_VLEN(ctt->ctt_info); size_t size, increment; + uint_t vlen, kind; + int isroot; - get_ctt_size(ctt, &size, &increment); + get_ctt_info(h, v, &kind, &vlen, &isroot); + get_ctt_size(h, v, &size, &increment); - switch (CTF_INFO_KIND(ctt->ctt_info)) { + switch (kind) { case CTF_K_INTEGER: case CTF_K_FLOAT: dptr += 4; @@ -799,17 +828,31 @@ count_types(ctf_header_t *h, caddr_t data) case CTF_K_CONST: case CTF_K_RESTRICT: case CTF_K_FUNCTION: - dptr += sizeof (ushort_t) * (vlen + (vlen & 1)); + dptr += idwidth * vlen; break; case CTF_K_ARRAY: - dptr += sizeof (ctf_array_t); + if (version == CTF_VERSION_2) + dptr += sizeof (struct ctf_array_v2); + else + dptr += sizeof (struct ctf_array_v3); break; case CTF_K_STRUCT: case CTF_K_UNION: - if (size < CTF_LSTRUCT_THRESH) - dptr += sizeof (ctf_member_t) * vlen; - else - dptr += sizeof (ctf_lmember_t) * vlen; + if (version == CTF_VERSION_2) { + if (size < CTF_V2_LSTRUCT_THRESH) + dptr += sizeof (struct ctf_member_v2) * + vlen; + else + dptr += sizeof (struct ctf_lmember_v2) * + vlen; + } else { + if (size < CTF_V3_LSTRUCT_THRESH) + dptr += sizeof (struct ctf_member_v3) * + vlen; + else + dptr += sizeof (struct ctf_lmember_v3) * + vlen; + } break; case CTF_K_ENUM: dptr += sizeof (ctf_enum_t) * vlen; @@ -818,7 +861,7 @@ count_types(ctf_header_t *h, caddr_t data) break; default: parseterminate("Unknown CTF type %d (#%d) at %#x", - CTF_INFO_KIND(ctt->ctt_info), count, dptr - data); + kind, count, dptr - data); } dptr += increment; @@ -895,11 +938,15 @@ resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, caddr_t buf = ctfdata + h->cth_objtoff; size_t bufsz = h->cth_funcoff - h->cth_objtoff; caddr_t dptr; + size_t idwidth; + + idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; symit_reset(si); - for (dptr = buf; dptr < buf + bufsz; dptr += 2) { - void *v = (void *) dptr; - ushort_t id = *((ushort_t *)v); + for (dptr = buf; dptr < buf + bufsz; dptr += idwidth) { + uint32_t id = 0; + + memcpy(&id, (void *) dptr, idwidth); iidesc_t *ii; GElf_Sym *sym; @@ -912,7 +959,7 @@ resurrect_objects(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, if (id == 0) { debug(3, "Skipping null object\n"); continue; - } else if (id >= tdsize) { + } else if (id >= (uint_t)tdsize) { parseterminate("Reference to invalid type %d", id); } @@ -937,18 +984,21 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, { caddr_t buf = ctfdata + h->cth_funcoff; size_t bufsz = h->cth_typeoff - h->cth_funcoff; + size_t idwidth; caddr_t dptr = buf; iidesc_t *ii; - ushort_t info; - ushort_t retid; GElf_Sym *sym; int i; + idwidth = h->cth_version == CTF_VERSION_2 ? 2 : 4; + symit_reset(si); while (dptr < buf + bufsz) { - void *v = (void *) dptr; - info = *((ushort_t *)v); - dptr += 2; + uint32_t id, info, retid; + + info = 0; + memcpy(&info, (void *) dptr, idwidth); + dptr += idwidth; if (!(sym = symit_next(si, STT_FUNC)) && info != 0) parseterminate("Unexpected end of function symbols"); @@ -959,11 +1009,11 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, continue; } - v = (void *) dptr; - retid = *((ushort_t *)v); - dptr += 2; + retid = 0; + memcpy(&retid, (void *) dptr, idwidth); + dptr += idwidth; - if (retid >= tdsize) + if (retid >= (uint_t)tdsize) parseterminate("Reference to invalid type %d", retid); ii = iidesc_new(symit_name(si)); @@ -973,15 +1023,18 @@ resurrect_functions(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, ii->ii_owner = xstrdup(symit_curfile(si)); } else ii->ii_type = II_GFUN; - ii->ii_nargs = CTF_INFO_VLEN(info); + if (h->cth_version == CTF_VERSION_2) + ii->ii_nargs = CTF_V2_INFO_VLEN(info); + else + ii->ii_nargs = CTF_V3_INFO_VLEN(info); if (ii->ii_nargs) ii->ii_args = xmalloc(sizeof (tdesc_t *) * ii->ii_nargs); - for (i = 0; i < ii->ii_nargs; i++, dptr += 2) { - v = (void *) dptr; - ushort_t id = *((ushort_t *)v); - if (id >= tdsize) + for (i = 0; i < ii->ii_nargs; i++, dptr += idwidth) { + id = 0; + memcpy(&id, (void *) dptr, idwidth); + if (id >= (uint_t)tdsize) parseterminate("Reference to invalid type %d", id); ii->ii_args[i] = tdarr[id]; @@ -1011,55 +1064,65 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, tdesc_t *tdp; uint_t data; uint_t encoding; - size_t size, increment; + size_t idwidth, size, increment; int tcnt; int iicnt = 0; tid_t tid, argid; - int kind, vlen; - int i; + int isroot, kind, vlen; + int i, version; elist_t **epp; mlist_t **mpp; intr_t *ip; - ctf_type_t *ctt; - ctf_array_t *cta; - ctf_enum_t *cte; + version = h->cth_version; + idwidth = version == CTF_VERSION_2 ? 2 : 4; /* * A maxid of zero indicates a request to resurrect all types, so reset * maxid to the maximum type id. */ - if (maxid == 0) - maxid = CTF_MAX_TYPE; + if (maxid == 0) { + maxid = version == CTF_VERSION_2 ? + CTF_V2_MAX_TYPE : CTF_V3_MAX_TYPE; + } for (dptr = buf, tcnt = 0, tid = 1; dptr < buf + bufsz; tcnt++, tid++) { + ctf_enum_t *cte; + uint_t name, type; + void *v; + if (tid > maxid) break; if (tid >= tdsize) parseterminate("Reference to invalid type %d", tid); - void *v = (void *) dptr; - ctt = v; + get_ctt_info(h, dptr, &kind, &vlen, &isroot); + get_ctt_size(h, dptr, &size, &increment); + if (version == CTF_VERSION_2) { + struct ctf_type_v2 *ctt = (void *) dptr; - get_ctt_size(ctt, &size, &increment); + name = ctt->ctt_name; + type = ctt->ctt_type; + } else { + struct ctf_type_v3 *ctt = (void *) dptr; + + name = ctt->ctt_name; + type = ctt->ctt_type; + } dptr += increment; tdp = tdarr[tid]; - if (CTF_NAME_STID(ctt->ctt_name) != CTF_STRTAB_0) + if (CTF_NAME_STID(name) != CTF_STRTAB_0) parseterminate( "Unable to cope with non-zero strtab id"); - if (CTF_NAME_OFFSET(ctt->ctt_name) != 0) { - tdp->t_name = - xstrdup(sbuf + CTF_NAME_OFFSET(ctt->ctt_name)); + if (CTF_NAME_OFFSET(name) != 0) { + tdp->t_name = xstrdup(sbuf + CTF_NAME_OFFSET(name)); } else tdp->t_name = NULL; - kind = CTF_INFO_KIND(ctt->ctt_info); - vlen = CTF_INFO_VLEN(ctt->ctt_info); - switch (kind) { case CTF_K_INTEGER: tdp->t_type = INTRINSIC; @@ -1106,62 +1169,110 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, case CTF_K_POINTER: tdp->t_type = POINTER; - tdp->t_tdesc = tdarr[ctt->ctt_type]; + tdp->t_tdesc = tdarr[type]; break; - case CTF_K_ARRAY: + case CTF_K_ARRAY: { + uint_t contents, index, nelems; + tdp->t_type = ARRAY; tdp->t_size = size; - v = (void *) dptr; - cta = v; - dptr += sizeof (ctf_array_t); + if (version == CTF_VERSION_2) { + struct ctf_array_v2 *cta = (void *) dptr; + contents = cta->cta_contents; + index = cta->cta_index; + nelems = cta->cta_nelems; + dptr += sizeof (*cta); + } else { + struct ctf_array_v3 *cta = (void *) dptr; + contents = cta->cta_contents; + index = cta->cta_index; + nelems = cta->cta_nelems; + dptr += sizeof (*cta); + } tdp->t_ardef = xmalloc(sizeof (ardef_t)); - tdp->t_ardef->ad_contents = tdarr[cta->cta_contents]; - tdp->t_ardef->ad_idxtype = tdarr[cta->cta_index]; - tdp->t_ardef->ad_nelems = cta->cta_nelems; + tdp->t_ardef->ad_contents = tdarr[contents]; + tdp->t_ardef->ad_idxtype = tdarr[index]; + tdp->t_ardef->ad_nelems = nelems; break; + } case CTF_K_STRUCT: - case CTF_K_UNION: + case CTF_K_UNION: { tdp->t_type = (kind == CTF_K_STRUCT ? STRUCT : UNION); tdp->t_size = size; - if (size < CTF_LSTRUCT_THRESH) { - for (i = 0, mpp = &tdp->t_members; i < vlen; - i++, mpp = &((*mpp)->ml_next)) { - v = (void *) dptr; - ctf_member_t *ctm = v; - dptr += sizeof (ctf_member_t); + if (version == CTF_VERSION_2) { + if (size < CTF_V2_LSTRUCT_THRESH) { + for (i = 0, mpp = &tdp->t_members; i < vlen; + i++, mpp = &((*mpp)->ml_next)) { + v = (void *) dptr; + struct ctf_member_v2 *ctm = v; + dptr += sizeof (struct ctf_member_v2); - *mpp = xmalloc(sizeof (mlist_t)); - (*mpp)->ml_name = xstrdup(sbuf + - ctm->ctm_name); - (*mpp)->ml_type = tdarr[ctm->ctm_type]; - (*mpp)->ml_offset = ctm->ctm_offset; - (*mpp)->ml_size = 0; + *mpp = xmalloc(sizeof (mlist_t)); + (*mpp)->ml_name = xstrdup(sbuf + + ctm->ctm_name); + (*mpp)->ml_type = tdarr[ctm->ctm_type]; + (*mpp)->ml_offset = ctm->ctm_offset; + (*mpp)->ml_size = 0; + } + } else { + for (i = 0, mpp = &tdp->t_members; i < vlen; + i++, mpp = &((*mpp)->ml_next)) { + v = (void *) dptr; + struct ctf_lmember_v2 *ctlm = v; + dptr += sizeof (struct ctf_lmember_v2); + + *mpp = xmalloc(sizeof (mlist_t)); + (*mpp)->ml_name = xstrdup(sbuf + + ctlm->ctlm_name); + (*mpp)->ml_type = + tdarr[ctlm->ctlm_type]; + (*mpp)->ml_offset = + (int)CTF_LMEM_OFFSET(ctlm); + (*mpp)->ml_size = 0; + } } } else { - for (i = 0, mpp = &tdp->t_members; i < vlen; - i++, mpp = &((*mpp)->ml_next)) { - v = (void *) dptr; - ctf_lmember_t *ctlm = v; - dptr += sizeof (ctf_lmember_t); + if (size < CTF_V3_LSTRUCT_THRESH) { + for (i = 0, mpp = &tdp->t_members; i < vlen; + i++, mpp = &((*mpp)->ml_next)) { + v = (void *) dptr; + struct ctf_member_v3 *ctm = v; + dptr += sizeof (struct ctf_member_v3); - *mpp = xmalloc(sizeof (mlist_t)); - (*mpp)->ml_name = xstrdup(sbuf + - ctlm->ctlm_name); - (*mpp)->ml_type = - tdarr[ctlm->ctlm_type]; - (*mpp)->ml_offset = - (int)CTF_LMEM_OFFSET(ctlm); - (*mpp)->ml_size = 0; + *mpp = xmalloc(sizeof (mlist_t)); + (*mpp)->ml_name = xstrdup(sbuf + + ctm->ctm_name); + (*mpp)->ml_type = tdarr[ctm->ctm_type]; + (*mpp)->ml_offset = ctm->ctm_offset; + (*mpp)->ml_size = 0; + } + } else { + for (i = 0, mpp = &tdp->t_members; i < vlen; + i++, mpp = &((*mpp)->ml_next)) { + v = (void *) dptr; + struct ctf_lmember_v3 *ctlm = v; + dptr += sizeof (struct ctf_lmember_v3); + + *mpp = xmalloc(sizeof (mlist_t)); + (*mpp)->ml_name = xstrdup(sbuf + + ctlm->ctlm_name); + (*mpp)->ml_type = + tdarr[ctlm->ctlm_type]; + (*mpp)->ml_offset = + (int)CTF_LMEM_OFFSET(ctlm); + (*mpp)->ml_size = 0; + } } } *mpp = NULL; break; + } case CTF_K_ENUM: tdp->t_type = ENUM; @@ -1187,26 +1298,26 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, case CTF_K_TYPEDEF: tdp->t_type = TYPEDEF; - tdp->t_tdesc = tdarr[ctt->ctt_type]; + tdp->t_tdesc = tdarr[type]; break; case CTF_K_VOLATILE: tdp->t_type = VOLATILE; - tdp->t_tdesc = tdarr[ctt->ctt_type]; + tdp->t_tdesc = tdarr[type]; break; case CTF_K_CONST: tdp->t_type = CONST; - tdp->t_tdesc = tdarr[ctt->ctt_type]; + tdp->t_tdesc = tdarr[type]; break; case CTF_K_FUNCTION: tdp->t_type = FUNCTION; tdp->t_fndef = xcalloc(sizeof (fndef_t)); - tdp->t_fndef->fn_ret = tdarr[ctt->ctt_type]; + tdp->t_fndef->fn_ret = tdarr[type]; - v = (void *) (dptr + (sizeof (ushort_t) * (vlen - 1))); - if (vlen > 0 && *(ushort_t *)v == 0) + v = (void *) (dptr + (idwidth * (vlen - 1))); + if (vlen > 0 && *(uint_t *)v == 0) tdp->t_fndef->fn_vargs = 1; tdp->t_fndef->fn_nargs = vlen - tdp->t_fndef->fn_vargs; @@ -1215,20 +1326,19 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, for (i = 0; i < vlen; i++) { v = (void *) dptr; - argid = *(ushort_t *)v; - dptr += sizeof (ushort_t); + memcpy(&argid, v, idwidth); + dptr += idwidth; if (argid != 0) tdp->t_fndef->fn_args[i] = tdarr[argid]; } - if (vlen & 1) - dptr += sizeof (ushort_t); + dptr = roundup2(dptr, 4); break; case CTF_K_RESTRICT: tdp->t_type = RESTRICT; - tdp->t_tdesc = tdarr[ctt->ctt_type]; + tdp->t_tdesc = tdarr[type]; break; case CTF_K_UNKNOWN: @@ -1238,7 +1348,7 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, warning("Can't parse unknown CTF type %d\n", kind); } - if (CTF_INFO_ISROOT(ctt->ctt_info)) { + if (isroot) { iidesc_t *ii = iidesc_new(tdp->t_name); if (tdp->t_type == STRUCT || tdp->t_type == UNION || tdp->t_type == ENUM) @@ -1252,8 +1362,7 @@ resurrect_types(ctf_header_t *h, tdata_t *td, tdesc_t **tdarr, int tdsize, } debug(3, "Resurrected %d %stype %s (%d)\n", tdp->t_type, - (CTF_INFO_ISROOT(ctt->ctt_info) ? "root " : ""), - tdesc_name(tdp), tdp->t_id); + (isroot ? "root " : ""), tdesc_name(tdp), tdp->t_id); } debug(3, "Resurrected %d types (%d were roots)\n", tcnt, iicnt); @@ -1353,7 +1462,7 @@ ctf_load(char *file, caddr_t buf, size_t bufsz, symit_data_t *si, char *label) if (h->cth_magic != CTF_MAGIC) parseterminate("Corrupt CTF - bad magic 0x%x", h->cth_magic); - if (h->cth_version != CTF_VERSION) + if (h->cth_version != CTF_VERSION_2 && h->cth_version != CTF_VERSION_3) parseterminate("Unknown CTF version %d", h->cth_version); ctfdatasz = h->cth_stroff + h->cth_strlen; diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c index ddb5f388ca98..161927cf0663 100644 --- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c +++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c @@ -972,11 +972,11 @@ main(int argc, char **argv) savetd = tdata_new(); - if (CTF_TYPE_ISCHILD(reftd->td_nextid)) + if (CTF_V3_TYPE_ISCHILD(reftd->td_nextid)) terminate("No room for additional types in master\n"); savetd->td_nextid = withfile ? reftd->td_nextid : - CTF_INDEX_TO_TYPE(1, TRUE); + CTF_V3_INDEX_TO_TYPE(1, TRUE); merge_into_master(mstrtd, reftd, savetd, 0); tdata_label_add(savetd, label, CTF_LABEL_LASTIDX); diff --git a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c index 740485ddff03..6da2c2cf8b26 100644 --- a/cddl/contrib/opensolaris/tools/ctf/dump/dump.c +++ b/cddl/contrib/opensolaris/tools/ctf/dump/dump.c @@ -97,6 +97,8 @@ typedef struct ctf_data { caddr_t cd_ctfdata; /* Pointer to the CTF data */ size_t cd_ctflen; /* Length of CTF data */ + size_t cd_idwidth; /* Size of a type ID, in bytes */ + /* * cd_symdata will be non-NULL if the CTF data is being retrieved from * an ELF file with a symbol table. cd_strdata and cd_nsyms should be @@ -266,9 +268,8 @@ next_sym(const ctf_data_t *cd, const int symidx, const uchar_t matchtype, static int read_data(const ctf_header_t *hp, const ctf_data_t *cd) { - void *v = (void *) (cd->cd_ctfdata + hp->cth_objtoff); - const ushort_t *idp = v; - ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / sizeof (ushort_t); + const char *v = (void *) (cd->cd_ctfdata + hp->cth_objtoff); + ulong_t n = (hp->cth_funcoff - hp->cth_objtoff) / cd->cd_idwidth; if (flags != F_STATS) print_line("- Data Objects "); @@ -287,6 +288,7 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd) char *name = NULL; for (symidx = -1, i = 0; i < (int) n; i++) { + uint32_t id = 0; int nextsym; if (cd->cd_symdata == NULL || (nextsym = next_sym(cd, @@ -295,7 +297,9 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd) else symidx = nextsym; - len = printf(" [%u] %u", i, *idp++); + memcpy(&id, v, cd->cd_idwidth); + v += cd->cd_idwidth; + len = printf(" [%u] %u", i, id); if (name != NULL) (void) printf("%*s%s (%u)", (15 - len), "", name, symidx); @@ -310,11 +314,10 @@ read_data(const ctf_header_t *hp, const ctf_data_t *cd) static int read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) { - void *v = (void *) (cd->cd_ctfdata + hp->cth_funcoff); - const ushort_t *fp = v; + const char *v = (void *) (cd->cd_ctfdata + hp->cth_funcoff); + uint_t f = 0, info; - v = (void *) (cd->cd_ctfdata + hp->cth_typeoff); - const ushort_t *end = v; + const char *end = (void *) (cd->cd_ctfdata + hp->cth_typeoff); ulong_t id; int symidx; @@ -331,10 +334,14 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) if (hp->cth_funcoff > hp->cth_typeoff) WARN("file is corrupt -- cth_funcoff > cth_typeoff\n"); - for (symidx = -1, id = 0; fp < end; id++) { - ushort_t info = *fp++; - ushort_t kind = CTF_INFO_KIND(info); - ushort_t n = CTF_INFO_VLEN(info); + for (symidx = -1, id = 0; v < end; id++) { + info = 0; + memcpy(&info, v, cd->cd_idwidth); + v += cd->cd_idwidth; + ushort_t kind = hp->cth_version == CTF_VERSION_2 ? + CTF_V2_INFO_KIND(info) : CTF_V3_INFO_KIND(info); + ushort_t n = hp->cth_version == CTF_VERSION_2 ? + CTF_V2_INFO_VLEN(info) : CTF_V3_INFO_VLEN(info); ushort_t i; int nextsym; char *name; @@ -354,7 +361,7 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) return (E_ERROR); } - if (fp + n > end) { + if (v + n * cd->cd_idwidth > end) { (void) printf(" [%lu] vlen %u extends past section " "boundary\n", id, n); return (E_ERROR); @@ -364,17 +371,24 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) (void) printf(" [%lu] FUNC ", id); if (name != NULL) (void) printf("(%s) ", name); - (void) printf("returns: %u args: (", *fp++); + memcpy(&f, v, cd->cd_idwidth); + v += cd->cd_idwidth; + (void) printf("returns: %u args: (", f); if (n != 0) { - (void) printf("%u", *fp++); - for (i = 1; i < n; i++) - (void) printf(", %u", *fp++); + memcpy(&f, v, cd->cd_idwidth); + v += cd->cd_idwidth; + (void) printf("%u", f); + for (i = 1; i < n; i++) { + memcpy(&f, v, cd->cd_idwidth); + v += cd->cd_idwidth; + (void) printf(", %u", f); + } } (void) printf(")\n"); } else - fp += n + 1; /* skip to next function definition */ + v += n * cd->cd_idwidth + 1; /* skip to next function definition */ stats.s_nfunc++; stats.s_nargs += n; @@ -387,13 +401,10 @@ read_funcs(const ctf_header_t *hp, const ctf_data_t *cd) static int read_types(const ctf_header_t *hp, const ctf_data_t *cd) { - void *v = (void *) (cd->cd_ctfdata + hp->cth_typeoff); - const ctf_type_t *tp = v; - - v = (void *) (cd->cd_ctfdata + hp->cth_stroff); - const ctf_type_t *end = v; - + const char *v = (void *) (cd->cd_ctfdata + hp->cth_typeoff); + const char *end = (void *) (cd->cd_ctfdata + hp->cth_stroff); ulong_t id; + uint_t version; if (flags != F_STATS) print_line("- Types "); @@ -407,103 +418,158 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd) if (hp->cth_typeoff > hp->cth_stroff) WARN("file is corrupt -- cth_typeoff > cth_stroff\n"); + version = hp->cth_version; + id = 1; if (hp->cth_parlabel || hp->cth_parname) - id += 1 << CTF_PARENT_SHIFT; + id += 1ul << (hp->cth_version == CTF_VERSION_2 ? + CTF_V2_PARENT_SHIFT : CTF_V3_PARENT_SHIFT); - for (/* */; tp < end; id++) { - ulong_t i, n = CTF_INFO_VLEN(tp->ctt_info); + for (/* */; v < end; id++) { + struct ctf_type_v2 t2; + struct ctf_type_v3 t3; + ulong_t i, n; size_t size, increment, vlen = 0; - int kind = CTF_INFO_KIND(tp->ctt_info); + uint_t isroot, name, type; + int kind; + + if (version == CTF_VERSION_2) { + memcpy(&t2, v, sizeof(t2)); + name = t2.ctt_name; + n = CTF_V2_INFO_VLEN(t2.ctt_info); + isroot = CTF_V2_INFO_ISROOT(t2.ctt_info); + kind = CTF_V2_INFO_KIND(t2.ctt_info); + type = t2.ctt_type; + + if (t2.ctt_size == CTF_V2_LSIZE_SENT) { + increment = sizeof (struct ctf_type_v2); + size = (size_t)CTF_TYPE_LSIZE(&t2); + } else { + increment = sizeof (struct ctf_stype_v2); + size = t2.ctt_size; + } + } else { + memcpy(&t3, v, sizeof(t3)); + name = t3.ctt_name; + n = CTF_V3_INFO_VLEN(t3.ctt_info); + isroot = CTF_V3_INFO_ISROOT(t3.ctt_info); + kind = CTF_V3_INFO_KIND(t3.ctt_info); + type = t3.ctt_type; + + if (t3.ctt_size == CTF_V3_LSIZE_SENT) { + increment = sizeof (struct ctf_type_v3); + size = (size_t)CTF_TYPE_LSIZE(&t3); + } else { + increment = sizeof (struct ctf_stype_v3); + size = t3.ctt_size; + } + } union { - const void *ptr; - ctf_array_t *ap; - const ctf_member_t *mp; - const ctf_lmember_t *lmp; + const char *ptr; + struct ctf_array_v2 *ap2; + struct ctf_array_v3 *ap3; + const struct ctf_member_v2 *mp2; + const struct ctf_member_v3 *mp3; + const struct ctf_lmember_v2 *lmp2; + const struct ctf_lmember_v3 *lmp3; const ctf_enum_t *ep; - const ushort_t *argp; } u; + u.ptr = v + increment; + if (flags != F_STATS) { (void) printf(" %c%lu%c ", - "[<"[CTF_INFO_ISROOT(tp->ctt_info)], id, - "]>"[CTF_INFO_ISROOT(tp->ctt_info)]); + "[<"[isroot], id, "]>"[isroot]); } - if (tp->ctt_size == CTF_LSIZE_SENT) { - increment = sizeof (ctf_type_t); - size = (size_t)CTF_TYPE_LSIZE(tp); - } else { - increment = sizeof (ctf_stype_t); - size = tp->ctt_size; - } - u.ptr = (const char *)tp + increment; - switch (kind) { case CTF_K_INTEGER: if (flags != F_STATS) { - uint_t encoding = *((const uint_t *)u.ptr); + uint_t encoding = + *((const uint_t *)(const void *)u.ptr); (void) printf("INTEGER %s encoding=%s offset=%u" - " bits=%u", ref_to_str(tp->ctt_name, hp, - cd), int_encoding_to_str( + " bits=%u", ref_to_str(name, hp, cd), + int_encoding_to_str( CTF_INT_ENCODING(encoding)), CTF_INT_OFFSET(encoding), CTF_INT_BITS(encoding)); } - vlen = sizeof (uint_t); + vlen = sizeof (uint32_t); break; case CTF_K_FLOAT: if (flags != F_STATS) { - uint_t encoding = *((const uint_t *)u.ptr); + uint_t encoding = + *((const uint_t *)(const void *)u.ptr); (void) printf("FLOAT %s encoding=%s offset=%u " - "bits=%u", ref_to_str(tp->ctt_name, hp, - cd), fp_encoding_to_str( + "bits=%u", ref_to_str(name, hp, cd), + fp_encoding_to_str( CTF_FP_ENCODING(encoding)), CTF_FP_OFFSET(encoding), CTF_FP_BITS(encoding)); } - vlen = sizeof (uint_t); + vlen = sizeof (uint32_t); break; case CTF_K_POINTER: if (flags != F_STATS) { (void) printf("POINTER %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); } break; - case CTF_K_ARRAY: + case CTF_K_ARRAY: { + uint_t contents, index, nelems; + + if (version == CTF_VERSION_2) { + contents = u.ap2->cta_contents; + index = u.ap2->cta_index; + nelems = u.ap2->cta_nelems; + } else { + contents = u.ap3->cta_contents; + index = u.ap3->cta_index; + nelems = u.ap3->cta_nelems; + } if (flags != F_STATS) { (void) printf("ARRAY %s content: %u index: %u " - "nelems: %u\n", ref_to_str(tp->ctt_name, - hp, cd), u.ap->cta_contents, - u.ap->cta_index, u.ap->cta_nelems); + "nelems: %u\n", ref_to_str(name, hp, cd), + contents, index, nelems); } - vlen = sizeof (ctf_array_t); + if (version == 2) + vlen = sizeof (struct ctf_array_v2); + else + vlen = sizeof (struct ctf_array_v3); break; + } + + case CTF_K_FUNCTION: { + uint_t arg = 0; - case CTF_K_FUNCTION: if (flags != F_STATS) { (void) printf("FUNCTION %s returns: %u args: (", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); if (n != 0) { - (void) printf("%u", *u.argp++); - for (i = 1; i < n; i++, u.argp++) - (void) printf(", %u", *u.argp); + memcpy(&arg, u.ptr, cd->cd_idwidth); + u.ptr += cd->cd_idwidth; + (void) printf("%u", arg); + for (i = 1; i < n; + i++, u.ptr += cd->cd_idwidth) { + memcpy(&arg, u.ptr, + cd->cd_idwidth); + (void) printf(", %u", arg); + } } (void) printf(")"); } - vlen = sizeof (ushort_t) * (n + (n & 1)); + vlen = roundup2(cd->cd_idwidth * n, 4); break; + } case CTF_K_STRUCT: case CTF_K_UNION: @@ -527,36 +593,64 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd) if (flags != F_STATS) { (void) printf(" %s (%zd bytes)\n", - ref_to_str(tp->ctt_name, hp, cd), size); + ref_to_str(name, hp, cd), size); - if (size >= CTF_LSTRUCT_THRESH) { - for (i = 0; i < n; i++, u.lmp++) { - (void) printf( - "\t%s type=%u off=%llu\n", - ref_to_str(u.lmp->ctlm_name, - hp, cd), u.lmp->ctlm_type, - (unsigned long long) - CTF_LMEM_OFFSET(u.lmp)); + if (version == CTF_VERSION_2) { + if (size >= CTF_V2_LSTRUCT_THRESH) { + for (i = 0; i < n; i++, u.lmp2++) { + (void) printf( + "\t%s type=%u off=%llu\n", + ref_to_str(u.lmp2->ctlm_name, + hp, cd), u.lmp2->ctlm_type, + (unsigned long long) + CTF_LMEM_OFFSET(u.lmp2)); + } + } else { + for (i = 0; i < n; i++, u.mp2++) { + (void) printf( + "\t%s type=%u off=%u\n", + ref_to_str(u.mp2->ctm_name, + hp, cd), u.mp2->ctm_type, + u.mp2->ctm_offset); + } } } else { - for (i = 0; i < n; i++, u.mp++) { - (void) printf( - "\t%s type=%u off=%u\n", - ref_to_str(u.mp->ctm_name, - hp, cd), u.mp->ctm_type, - u.mp->ctm_offset); + if (size >= CTF_V3_LSTRUCT_THRESH) { + for (i = 0; i < n; i++, u.lmp3++) { + (void) printf( + "\t%s type=%u off=%llu\n", + ref_to_str(u.lmp3->ctlm_name, + hp, cd), u.lmp3->ctlm_type, + (unsigned long long) + CTF_LMEM_OFFSET(u.lmp3)); + } + } else { + for (i = 0; i < n; i++, u.mp3++) { + (void) printf( + "\t%s type=%u off=%u\n", + ref_to_str(u.mp3->ctm_name, + hp, cd), u.mp3->ctm_type, + u.mp3->ctm_offset); + } } } } - vlen = n * (size >= CTF_LSTRUCT_THRESH ? - sizeof (ctf_lmember_t) : sizeof (ctf_member_t)); + if (version == CTF_VERSION_2) { + vlen = n * (size >= CTF_V2_LSTRUCT_THRESH ? + sizeof (struct ctf_lmember_v2) : + sizeof (struct ctf_member_v2)); + } else { + vlen = n * (size >= CTF_V3_LSTRUCT_THRESH ? + sizeof (struct ctf_lmember_v3) : + sizeof (struct ctf_member_v3)); + } break; case CTF_K_ENUM: if (flags != F_STATS) { (void) printf("ENUM %s\n", - ref_to_str(tp->ctt_name, hp, cd)); + ref_to_str(name, hp, cd)); for (i = 0; i < n; i++, u.ep++) { (void) printf("\t%s = %d\n", @@ -574,39 +668,35 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd) case CTF_K_FORWARD: if (flags != F_STATS) { (void) printf("FORWARD %s", - ref_to_str(tp->ctt_name, hp, cd)); + ref_to_str(name, hp, cd)); } break; case CTF_K_TYPEDEF: if (flags != F_STATS) { (void) printf("TYPEDEF %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); } break; case CTF_K_VOLATILE: if (flags != F_STATS) { (void) printf("VOLATILE %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); } break; case CTF_K_CONST: if (flags != F_STATS) { (void) printf("CONST %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); } break; case CTF_K_RESTRICT: if (flags != F_STATS) { (void) printf("RESTRICT %s refers to %u", - ref_to_str(tp->ctt_name, hp, cd), - tp->ctt_type); + ref_to_str(name, hp, cd), type); } break; @@ -624,7 +714,7 @@ read_types(const ctf_header_t *hp, const ctf_data_t *cd) stats.s_ntypes++; stats.s_types[kind]++; - tp = (ctf_type_t *)((uintptr_t)tp + increment + vlen); + v += increment + vlen; } return (E_SUCCESS); @@ -935,14 +1025,16 @@ main(int argc, char *argv[]) if (pp->ctp_magic != CTF_MAGIC) die("%s does not appear to contain CTF data\n", filename); - if (pp->ctp_version == CTF_VERSION) { + if (pp->ctp_version >= CTF_VERSION_2) { v = (void *) cd.cd_ctfdata; hp = v; cd.cd_ctfdata = (caddr_t)cd.cd_ctfdata + sizeof (ctf_header_t); + cd.cd_idwidth = pp->ctp_version == CTF_VERSION_2 ? 2 : 4; + if (cd.cd_ctflen < sizeof (ctf_header_t)) { die("%s does not contain a v%d CTF header\n", filename, - CTF_VERSION); + pp->ctp_version); } } else { diff --git a/sys/sys/ctf.h b/sys/sys/ctf.h index 4072e318320c..1a724c842fef 100644 --- a/sys/sys/ctf.h +++ b/sys/sys/ctf.h @@ -149,7 +149,7 @@ typedef struct ctf_enum { } ctf_enum_t; #define CTF_MAGIC 0xcff1 -#define CTF_VERSION CTF_VERSION_2 +#define CTF_VERSION CTF_VERSION_3 #define CTF_VERSION_3 3 #define CTF_VERSION_2 2 #define CTF_VERSION_1 1