Index: cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c =================================================================== --- cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c +++ cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c @@ -278,12 +278,93 @@ } static int +sou_count_members(tdesc_t *tp) +{ + mlist_t *mp; + int i; + + if (tp->t_type != STRUCT && tp->t_type != UNION) + return (0); + + for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) { + /* Recurse for unnamed struct/union members. */ + if (mp->ml_name[0] == '\0') + i += sou_count_members(mp->ml_type); + else + i++; + } + return (i); +} + +static void +sou_write_members(tdesc_t *tp, ctf_buf_t *b, int delta) +{ + ctf_member_t ctm; + mlist_t *mp; + size_t offset; + + if (tp->t_type != STRUCT && tp->t_type != UNION) + return; + + for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { + if (mp->ml_name[0] == '\0') { + sou_write_members(mp->ml_type, b, + delta + mp->ml_offset); + continue; + } + offset = strtab_insert(&b->ctb_strtab, mp->ml_name); + ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); + ctm.ctm_type = mp->ml_type->t_id; + ctm.ctm_offset = mp->ml_offset + delta; + if (target_requires_swap) { + SWAP_32(ctm.ctm_name); + SWAP_16(ctm.ctm_type); + SWAP_16(ctm.ctm_offset); + } + ctf_buf_write(b, &ctm, sizeof (ctm)); + } +} + +static void +sou_write_members_large(tdesc_t *tp, ctf_buf_t *b, int delta) +{ + ctf_lmember_t ctlm; + mlist_t *mp; + size_t offset; + + if (tp->t_type != STRUCT && tp->t_type != UNION) + return; + + for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { + if (mp->ml_name[0] == '\0') { + sou_write_members_large(mp->ml_type, b, + delta + mp->ml_offset); + continue; + } + offset = strtab_insert(&b->ctb_strtab, mp->ml_name); + ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset); + ctlm.ctlm_type = mp->ml_type->t_id; + ctlm.ctlm_pad = 0; + ctlm.ctlm_offsethi = + CTF_OFFSET_TO_LMEMHI(mp->ml_offset + delta); + ctlm.ctlm_offsetlo = + CTF_OFFSET_TO_LMEMLO(mp->ml_offset + delta); + if (target_requires_swap) { + SWAP_32(ctlm.ctlm_name); + SWAP_16(ctlm.ctlm_type); + SWAP_32(ctlm.ctlm_offsethi); + SWAP_32(ctlm.ctlm_offsetlo); + } + ctf_buf_write(b, &ctlm, sizeof (ctlm)); + } +} + +static int write_type(void *arg1, void *arg2) { tdesc_t *tp = arg1; ctf_buf_t *b = arg2; elist_t *ep; - mlist_t *mp; intr_t *ip; size_t offset; @@ -294,13 +375,9 @@ 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; - /* * There shouldn't be any holes in the type list (where a hole is * defined as two consecutive tdescs without consecutive ids), but @@ -377,9 +454,7 @@ case STRUCT: case UNION: - for (i = 0, mp = tp->t_members; mp != NULL; mp = mp->ml_next) - i++; /* count up struct or union members */ - + i = sou_count_members(tp); if (i > CTF_MAX_VLEN) { terminate("sou %s has too many members: %d > %d\n", tdesc_name(tp), i, CTF_MAX_VLEN); @@ -392,45 +467,10 @@ write_sized_type_rec(b, &ctt, tp->t_size); - if (tp->t_size < CTF_LSTRUCT_THRESH) { - for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { - offset = strtab_insert(&b->ctb_strtab, - mp->ml_name); - - ctm.ctm_name = CTF_TYPE_NAME(CTF_STRTAB_0, - offset); - ctm.ctm_type = mp->ml_type->t_id; - 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); - } - ctf_buf_write(b, &ctm, sizeof (ctm)); - } - } else { - for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { - offset = strtab_insert(&b->ctb_strtab, - mp->ml_name); - - ctlm.ctlm_name = CTF_TYPE_NAME(CTF_STRTAB_0, - offset); - ctlm.ctlm_type = mp->ml_type->t_id; - ctlm.ctlm_offsethi = - CTF_OFFSET_TO_LMEMHI(mp->ml_offset); - ctlm.ctlm_offsetlo = - CTF_OFFSET_TO_LMEMLO(mp->ml_offset); - - if (target_requires_swap) { - SWAP_32(ctlm.ctlm_name); - SWAP_16(ctlm.ctlm_type); - SWAP_32(ctlm.ctlm_offsethi); - SWAP_32(ctlm.ctlm_offsetlo); - } - - ctf_buf_write(b, &ctlm, sizeof (ctlm)); - } - } + if (tp->t_size < CTF_LSTRUCT_THRESH) + sou_write_members(tp, b, 0); + else + sou_write_members_large(tp, b, 0); break; case ENUM: