The branch stable/13 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e5b54808f735f1a74716f1320916b8a961ddf92d

commit e5b54808f735f1a74716f1320916b8a961ddf92d
Author:     Mark Johnston <[email protected]>
AuthorDate: 2022-03-07 13:54:18 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2022-04-07 00:30:45 +0000

    ctf: Add v3 support to CTF tools, ctf{convert,dump,merge}
    
    ctfdump handles v2 and v3.  ctfconvert now emits only CTFv3, whereas
    ctfmerge can merge v2 and v3 containers into v3 containers.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit bdf290cd3e1a69d41c2f8bb60bd415cfa78adba2)
---
 cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c      | 453 ++++++++++++++--------
 cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c |   4 +-
 cddl/contrib/opensolaris/tools/ctf/dump/dump.c    | 286 +++++++++-----
 sys/sys/ctf.h                                     |   2 +-
 4 files changed, 473 insertions(+), 272 deletions(-)

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 (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 {
+               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 (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;
+
+               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 {
-               *sizep = ctt->ctt_size;
-               *incrementp = sizeof (ctf_stype_t);
+               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);
-
-                                       *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;
+                       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;
+                                       }
+                               } 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);
-
-                                       *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;
+                               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 +
+                                                   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;
*** 446 LINES SKIPPED ***

Reply via email to