The branch stable/13 has been updated by markj:

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

commit 2ecf3b58ebdfd6452b8ce269943da362b40c2e63
Author:     Mark Johnston <[email protected]>
AuthorDate: 2022-03-07 13:45:53 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2022-04-07 00:30:44 +0000

    fbt: Add support for CTFv3 containers
    
    The general aim in this and subsequent patches is to minimize the
    amount of code that directly references CTF types such as ctf_type_t,
    ctf_array_t, etc.  To that end, introduce some routines similar to the
    existing fbt_get_ctt_size() (which exists to deal with differences
    between v1 and v2) and change ctf_lookup_by_id() to return a void
    pointer.
    
    Support for v2 containers is preserved.
    
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit d9175438c0e77ef2b400601aa8cf8098c82a77a7)
---
 sys/cddl/dev/fbt/fbt.c | 309 ++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 231 insertions(+), 78 deletions(-)

diff --git a/sys/cddl/dev/fbt/fbt.c b/sys/cddl/dev/fbt/fbt.c
index 5b1aeab3bafb..aee5376d5981 100644
--- a/sys/cddl/dev/fbt/fbt.c
+++ b/sys/cddl/dev/fbt/fbt.c
@@ -370,12 +370,12 @@ fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
        const Elf_Sym *symp = lc->symtab;
        const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
        const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
+       size_t idwidth;
        int i;
        uint32_t *ctfoff;
        uint32_t objtoff = hp->cth_objtoff;
        uint32_t funcoff = hp->cth_funcoff;
-       ushort_t info;
-       ushort_t vlen;
+       uint_t kind, info, vlen;
 
        /* Sanity check. */
        if (hp->cth_magic != CTF_MAGIC) {
@@ -391,6 +391,8 @@ fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
        ctfoff = malloc(sizeof(uint32_t) * lc->nsym, M_LINKER, M_WAITOK);
        *lc->ctfoffp = ctfoff;
 
+       idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4;
+
        for (i = 0; i < lc->nsym; i++, ctfoff++, symp++) {
                if (symp->st_name == 0 || symp->st_shndx == SHN_UNDEF) {
                        *ctfoff = 0xffffffff;
@@ -400,13 +402,13 @@ fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
                switch (ELF_ST_TYPE(symp->st_info)) {
                case STT_OBJECT:
                        if (objtoff >= hp->cth_funcoff ||
-                            (symp->st_shndx == SHN_ABS && symp->st_value == 
0)) {
+                           (symp->st_shndx == SHN_ABS && symp->st_value == 0)) 
{
                                *ctfoff = 0xffffffff;
-                                break;
-                        }
+                               break;
+                       }
 
-                        *ctfoff = objtoff;
-                        objtoff += sizeof (ushort_t);
+                       *ctfoff = objtoff;
+                       objtoff += idwidth;
                        break;
 
                case STT_FUNC:
@@ -417,18 +419,25 @@ fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
 
                        *ctfoff = funcoff;
 
-                       info = *((const ushort_t *)(ctfdata + funcoff));
-                       vlen = CTF_INFO_VLEN(info);
+                       info = 0;
+                       memcpy(&info, ctfdata + funcoff, idwidth);
+                       if (hp->cth_version == CTF_VERSION_2) {
+                               kind = CTF_V2_INFO_KIND(info);
+                               vlen = CTF_V2_INFO_VLEN(info);
+                       } else {
+                               kind = CTF_V3_INFO_KIND(info);
+                               vlen = CTF_V3_INFO_VLEN(info);
+                       }
 
                        /*
                         * If we encounter a zero pad at the end, just skip it.
                         * Otherwise skip over the function and its return type
                         * (+2) and the argument list (vlen).
                         */
-                       if (CTF_INFO_KIND(info) == CTF_K_UNKNOWN && vlen == 0)
-                               funcoff += sizeof (ushort_t); /* skip pad */
+                       if (kind == CTF_K_UNKNOWN && vlen == 0)
+                               funcoff += idwidth;
                        else
-                               funcoff += sizeof (ushort_t) * (vlen + 2);
+                               funcoff += idwidth * (vlen + 2);
                        break;
 
                default:
@@ -440,18 +449,61 @@ fbt_ctfoff_init(modctl_t *lf, linker_ctf_t *lc)
        return (0);
 }
 
+static void
+fbt_get_ctt_index(uint8_t version, const void *v, uint_t *indexp,
+    uint_t *typep, int *ischildp)
+{
+       uint_t index, type;
+       int ischild;
+
+       if (version == CTF_VERSION_2) {
+               const struct ctf_type_v2 *ctt = v;
+
+               type = ctt->ctt_type;
+               index = CTF_V2_TYPE_TO_INDEX(ctt->ctt_type);
+               ischild = CTF_V2_TYPE_ISCHILD(ctt->ctt_type);
+       } else {
+               const struct ctf_type_v3 *ctt = v;
+
+               type = ctt->ctt_type;
+               index = CTF_V3_TYPE_TO_INDEX(ctt->ctt_type);
+               ischild = CTF_V3_TYPE_ISCHILD(ctt->ctt_type);
+       }
+
+       if (indexp != NULL)
+               *indexp = index;
+       if (typep != NULL)
+               *typep = type;
+       if (ischildp != NULL)
+               *ischildp = ischild;
+}
+
 static ssize_t
-fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, ssize_t *sizep,
+fbt_get_ctt_size(uint8_t version, const void *tp, ssize_t *sizep,
     ssize_t *incrementp)
 {
        ssize_t size, increment;
 
-       if (tp->ctt_size == CTF_LSIZE_SENT) {
-               size = CTF_TYPE_LSIZE(tp);
-               increment = sizeof (ctf_type_t);
+       if (version == CTF_VERSION_2) {
+               const struct ctf_type_v2 *ctt = tp;
+
+               if (ctt->ctt_size == CTF_V2_LSIZE_SENT) {
+                       size = CTF_TYPE_LSIZE(ctt);
+                       increment = sizeof (struct ctf_type_v2);
+               } else {
+                       size = ctt->ctt_size;
+                       increment = sizeof (struct ctf_stype_v2);
+               }
        } else {
-               size = tp->ctt_size;
-               increment = sizeof (ctf_stype_t);
+               const struct ctf_type_v3 *ctt = tp;
+
+               if (ctt->ctt_size == CTF_V3_LSIZE_SENT) {
+                       size = CTF_TYPE_LSIZE(ctt);
+                       increment = sizeof (struct ctf_type_v3);
+               } else {
+                       size = ctt->ctt_size;
+                       increment = sizeof (struct ctf_stype_v3);
+               }
        }
 
        if (sizep)
@@ -462,41 +514,69 @@ fbt_get_ctt_size(uint8_t version, const ctf_type_t *tp, 
ssize_t *sizep,
        return (size);
 }
 
+static void
+fbt_get_ctt_info(uint8_t version, const void *tp, uint_t *kindp, uint_t *vlenp,
+    int *isrootp)
+{
+       uint_t kind, vlen;
+       int isroot;
+
+       if (version == CTF_VERSION_2) {
+               const struct ctf_type_v2 *ctt = tp;
+
+               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 {
+               const struct ctf_type_v3 *ctt = tp;
+
+               kind = CTF_V3_INFO_KIND(ctt->ctt_info);
+               vlen = CTF_V3_INFO_VLEN(ctt->ctt_info);
+               isroot = CTF_V3_INFO_ISROOT(ctt->ctt_info);
+       }
+
+       if (kindp != NULL)
+               *kindp = kind;
+       if (vlenp != NULL)
+               *vlenp = vlen;
+       if (isrootp != NULL)
+               *isrootp = isroot;
+}
+
 static int
 fbt_typoff_init(linker_ctf_t *lc)
 {
        const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
-       const ctf_type_t *tbuf;
-       const ctf_type_t *tend;
-       const ctf_type_t *tp;
+       const void *tbuf, *tend, *tp;
        const uint8_t *ctfdata = lc->ctftab + sizeof(ctf_header_t);
+       size_t idwidth;
        int ctf_typemax = 0;
        uint32_t *xp;
        ulong_t pop[CTF_K_MAX + 1] = { 0 };
        uint8_t version;
 
-
        /* Sanity check. */
        if (hp->cth_magic != CTF_MAGIC)
                return (EINVAL);
 
        version = hp->cth_version;
+       idwidth = version == CTF_VERSION_2 ? 2 : 4;
 
-       tbuf = (const ctf_type_t *) (ctfdata + hp->cth_typeoff);
-       tend = (const ctf_type_t *) (ctfdata + hp->cth_stroff);
+       tbuf = (const void *) (ctfdata + hp->cth_typeoff);
+       tend = (const void *) (ctfdata + hp->cth_stroff);
 
        /*
         * We make two passes through the entire type section.  In this first
         * pass, we count the number of each type and the total number of types.
         */
        for (tp = tbuf; tp < tend; ctf_typemax++) {
-               ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
-               ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
+               uint_t kind, type, vlen;
                ssize_t size, increment;
-
                size_t vbytes;
 
                (void) fbt_get_ctt_size(version, tp, &size, &increment);
+               fbt_get_ctt_info(version, tp, &kind, &vlen, NULL);
+               fbt_get_ctt_index(version, tp, NULL, &type, NULL);
 
                switch (kind) {
                case CTF_K_INTEGER:
@@ -504,17 +584,31 @@ fbt_typoff_init(linker_ctf_t *lc)
                        vbytes = sizeof (uint_t);
                        break;
                case CTF_K_ARRAY:
-                       vbytes = sizeof (ctf_array_t);
+                       if (version == CTF_VERSION_2)
+                               vbytes = sizeof (struct ctf_array_v2);
+                       else
+                               vbytes = sizeof (struct ctf_array_v3);
                        break;
                case CTF_K_FUNCTION:
-                       vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+                       vbytes = roundup2(idwidth * vlen, sizeof(uint32_t));
                        break;
                case CTF_K_STRUCT:
                case CTF_K_UNION:
-                       if (size < CTF_LSTRUCT_THRESH)
-                               vbytes = sizeof (ctf_member_t) * vlen;
-                       else
-                               vbytes = sizeof (ctf_lmember_t) * vlen;
+                       if (version == CTF_VERSION_2) {
+                               if (size < CTF_V2_LSTRUCT_THRESH)
+                                       vbytes =
+                                           sizeof (struct ctf_member_v2) * 
vlen;
+                               else
+                                       vbytes =
+                                           sizeof (struct ctf_lmember_v2) * 
vlen;
+                       } else {
+                               if (size < CTF_V3_LSTRUCT_THRESH)
+                                       vbytes =
+                                           sizeof (struct ctf_member_v3) * 
vlen;
+                               else
+                                       vbytes =
+                                           sizeof (struct ctf_lmember_v3) * 
vlen;
+                       }
                        break;
                case CTF_K_ENUM:
                        vbytes = sizeof (ctf_enum_t) * vlen;
@@ -525,11 +619,10 @@ fbt_typoff_init(linker_ctf_t *lc)
                         * kind for the tag, so bump that population count too.
                         * If ctt_type is unknown, treat the tag as a struct.
                         */
-                       if (tp->ctt_type == CTF_K_UNKNOWN ||
-                           tp->ctt_type >= CTF_K_MAX)
+                       if (type == CTF_K_UNKNOWN || type >= CTF_K_MAX)
                                pop[CTF_K_STRUCT]++;
                        else
-                               pop[tp->ctt_type]++;
+                               pop[type]++;
                        /*FALLTHRU*/
                case CTF_K_UNKNOWN:
                        vbytes = 0;
@@ -545,7 +638,7 @@ fbt_typoff_init(linker_ctf_t *lc)
                        printf("%s(%d): detected invalid CTF kind -- %u\n", 
__func__, __LINE__, kind);
                        return (EIO);
                }
-               tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+               tp = (const void *)((uintptr_t)tp + increment + vbytes);
                pop[kind]++;
        }
 
@@ -565,13 +658,13 @@ fbt_typoff_init(linker_ctf_t *lc)
         * In the second pass, fill in the type offset.
         */
        for (tp = tbuf; tp < tend; xp++) {
-               ushort_t kind = CTF_INFO_KIND(tp->ctt_info);
-               ulong_t vlen = CTF_INFO_VLEN(tp->ctt_info);
                ssize_t size, increment;
+               uint_t kind, vlen;
 
                size_t vbytes;
 
                (void) fbt_get_ctt_size(version, tp, &size, &increment);
+               fbt_get_ctt_info(version, tp, &kind, &vlen, NULL);
 
                switch (kind) {
                case CTF_K_INTEGER:
@@ -579,17 +672,31 @@ fbt_typoff_init(linker_ctf_t *lc)
                        vbytes = sizeof (uint_t);
                        break;
                case CTF_K_ARRAY:
-                       vbytes = sizeof (ctf_array_t);
+                       if (version == CTF_VERSION_2)
+                               vbytes = sizeof (struct ctf_array_v2);
+                       else
+                               vbytes = sizeof (struct ctf_array_v3);
                        break;
                case CTF_K_FUNCTION:
-                       vbytes = sizeof (ushort_t) * (vlen + (vlen & 1));
+                       vbytes = roundup2(idwidth * vlen, sizeof(uint32_t));
                        break;
                case CTF_K_STRUCT:
                case CTF_K_UNION:
-                       if (size < CTF_LSTRUCT_THRESH)
-                               vbytes = sizeof (ctf_member_t) * vlen;
-                       else
-                               vbytes = sizeof (ctf_lmember_t) * vlen;
+                       if (version == CTF_VERSION_2) {
+                               if (size < CTF_V2_LSTRUCT_THRESH)
+                                       vbytes =
+                                           sizeof (struct ctf_member_v2) * 
vlen;
+                               else
+                                       vbytes =
+                                           sizeof (struct ctf_lmember_v2) * 
vlen;
+                       } else {
+                               if (size < CTF_V3_LSTRUCT_THRESH)
+                                       vbytes =
+                                           sizeof (struct ctf_member_v3) * 
vlen;
+                               else
+                                       vbytes =
+                                           sizeof (struct ctf_lmember_v3) * 
vlen;
+                       }
                        break;
                case CTF_K_ENUM:
                        vbytes = sizeof (ctf_enum_t) * vlen;
@@ -610,7 +717,7 @@ fbt_typoff_init(linker_ctf_t *lc)
                        return (EIO);
                }
                *xp = (uint32_t)((uintptr_t) tp - (uintptr_t) ctfdata);
-               tp = (ctf_type_t *)((uintptr_t)tp + increment + vbytes);
+               tp = (const void *)((uintptr_t)tp + increment + vbytes);
        }
 
        return (0);
@@ -748,10 +855,10 @@ ctf_decl_fini(ctf_decl_t *cd)
        }
 }
 
-static const ctf_type_t *
+static const void *
 ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
 {
-       const ctf_type_t *tp;
+       const void *tp;
        uint32_t offset;
        uint32_t *typoff = *lc->typoffp;
 
@@ -766,7 +873,7 @@ ctf_lookup_by_id(linker_ctf_t *lc, ctf_id_t type)
                return(NULL);
        }
 
-       tp = (const ctf_type_t *)(lc->ctftab + offset + sizeof(ctf_header_t));
+       tp = (const void *) (lc->ctftab + offset + sizeof(ctf_header_t));
 
        return (tp);
 }
@@ -775,24 +882,36 @@ static void
 fbt_array_info(linker_ctf_t *lc, ctf_id_t type, ctf_arinfo_t *arp)
 {
        const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
-       const ctf_type_t *tp;
-       const ctf_array_t *ap;
+       const void *tp;
        ssize_t increment;
+       uint_t kind;
 
        bzero(arp, sizeof(*arp));
 
        if ((tp = ctf_lookup_by_id(lc, type)) == NULL)
                return;
 
-       if (CTF_INFO_KIND(tp->ctt_info) != CTF_K_ARRAY)
+       fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL);
+       if (kind != CTF_K_ARRAY)
                return;
 
        (void) fbt_get_ctt_size(hp->cth_version, tp, NULL, &increment);
 
-       ap = (const ctf_array_t *)((uintptr_t)tp + increment);
-       arp->ctr_contents = ap->cta_contents;
-       arp->ctr_index = ap->cta_index;
-       arp->ctr_nelems = ap->cta_nelems;
+       if (hp->cth_version == CTF_VERSION_2) {
+               const struct ctf_array_v2 *ap;
+
+               ap = (const struct ctf_array_v2 *)((uintptr_t)tp + increment);
+               arp->ctr_contents = ap->cta_contents;
+               arp->ctr_index = ap->cta_index;
+               arp->ctr_nelems = ap->cta_nelems;
+       } else {
+               const struct ctf_array_v3 *ap;
+
+               ap = (const struct ctf_array_v3 *)((uintptr_t)tp + increment);
+               arp->ctr_contents = ap->cta_contents;
+               arp->ctr_index = ap->cta_index;
+               arp->ctr_nelems = ap->cta_nelems;
+       }
 }
 
 static const char *
@@ -809,15 +928,35 @@ ctf_strptr(linker_ctf_t *lc, int name)
        return (strp);
 }
 
+static const char *
+ctf_type_rname(linker_ctf_t *lc, const void *v)
+{
+       const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
+       uint_t name;
+
+       if (hp->cth_version == CTF_VERSION_2) {
+               const struct ctf_type_v2 *ctt = v;
+
+               name = ctt->ctt_name;
+       } else {
+               const struct ctf_type_v3 *ctt = v;
+
+               name = ctt->ctt_name;
+       }
+
+       return (ctf_strptr(lc, name));
+}
+
 static void
 ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t type)
 {
+       const ctf_header_t *hp = (const ctf_header_t *) lc->ctftab;
        ctf_decl_node_t *cdp;
        ctf_decl_prec_t prec;
-       uint_t kind, n = 1;
+       uint_t kind, n = 1, t;
        int is_qual = 0;
 
-       const ctf_type_t *tp;
+       const void *tp;
        ctf_arinfo_t ar;
 
        if ((tp = ctf_lookup_by_id(lc, type)) == NULL) {
@@ -825,7 +964,10 @@ ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t 
type)
                return;
        }
 
-       switch (kind = CTF_INFO_KIND(tp->ctt_info)) {
+       fbt_get_ctt_info(hp->cth_version, tp, &kind, NULL, NULL);
+       fbt_get_ctt_index(hp->cth_version, tp, NULL, &t, NULL);
+
+       switch (kind) {
        case CTF_K_ARRAY:
                fbt_array_info(lc, type, &ar);
                ctf_decl_push(cd, lc, ar.ctr_contents);
@@ -834,27 +976,27 @@ ctf_decl_push(ctf_decl_t *cd, linker_ctf_t *lc, ctf_id_t 
type)
                break;
 
        case CTF_K_TYPEDEF:
-               if (ctf_strptr(lc, tp->ctt_name)[0] == '\0') {
-                       ctf_decl_push(cd, lc, tp->ctt_type);
+               if (ctf_type_rname(lc, tp)[0] == '\0') {
+                       ctf_decl_push(cd, lc, t);
                        return;
                }
                prec = CTF_PREC_BASE;
                break;
 
        case CTF_K_FUNCTION:
-               ctf_decl_push(cd, lc, tp->ctt_type);
+               ctf_decl_push(cd, lc, t);
                prec = CTF_PREC_FUNCTION;
                break;
 
        case CTF_K_POINTER:
-               ctf_decl_push(cd, lc, tp->ctt_type);
+               ctf_decl_push(cd, lc, t);
                prec = CTF_PREC_POINTER;
                break;
 
        case CTF_K_VOLATILE:
        case CTF_K_CONST:
        case CTF_K_RESTRICT:
-               ctf_decl_push(cd, lc, tp->ctt_type);
+               ctf_decl_push(cd, lc, t);
                prec = cd->cd_qualp;
                is_qual++;
                break;
@@ -943,9 +1085,8 @@ fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char *buf, 
size_t len)
                for (cdp = ctf_list_next(&cd.cd_nodes[prec]);
                    cdp != NULL; cdp = ctf_list_next(cdp)) {
 
-                       const ctf_type_t *tp =
-                           ctf_lookup_by_id(lc, cdp->cd_type);
-                       const char *name = ctf_strptr(lc, tp->ctt_name);
+                       const void *tp = ctf_lookup_by_id(lc, cdp->cd_type);
+                       const char *name = ctf_type_rname(lc, tp);
 
                        if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
                                ctf_decl_sprintf(&cd, " ");
@@ -1005,15 +1146,18 @@ fbt_type_name(linker_ctf_t *lc, ctf_id_t type, char 
*buf, size_t len)
 static void
 fbt_getargdesc(void *arg __unused, dtrace_id_t id __unused, void *parg, 
dtrace_argdesc_t *desc)
 {
-       const ushort_t *dp;
+       const ctf_header_t *hp;
+       const char *dp;
        fbt_probe_t *fbt = parg;
        linker_ctf_t lc;
        modctl_t *ctl = fbt->fbtp_ctl;
+       size_t idwidth;
        int ndx = desc->dtargd_ndx;
        int symindx = fbt->fbtp_symindx;
        uint32_t *ctfoff;
-       uint32_t offset;
-       ushort_t info, kind, n;
+       uint32_t offset, type;
+       uint_t info, n;
+       ushort_t kind;
 
        if (fbt->fbtp_roffset != 0 && desc->dtargd_ndx == 0) {
                (void) strcpy(desc->dtargd_native, "int");
@@ -1054,11 +1198,20 @@ fbt_getargdesc(void *arg __unused, dtrace_id_t id 
__unused, void *parg, dtrace_a
        if ((offset = ctfoff[symindx]) == 0xffffffff)
                return;
 
-       dp = (const ushort_t *)(lc.ctftab + offset + sizeof(ctf_header_t));
+       hp = (const ctf_header_t *) lc.ctftab;
+       idwidth = hp->cth_version == CTF_VERSION_2 ? 2 : 4;
+       dp = (const char *)(lc.ctftab + offset + sizeof(ctf_header_t));
 
-       info = *dp++;
-       kind = CTF_INFO_KIND(info);
-       n = CTF_INFO_VLEN(info);
+       info = 0;
+       memcpy(&info, dp, idwidth);
+       dp += idwidth;
+       if (hp->cth_version == CTF_VERSION_2) {
+               kind = CTF_V2_INFO_KIND(info);
+               n = CTF_V2_INFO_VLEN(info);
+       } else {
+               kind = CTF_V3_INFO_KIND(info);
+               n = CTF_V3_INFO_VLEN(info);
+       }
 
        if (kind == CTF_K_UNKNOWN && n == 0) {
                printf("%s(%d): Unknown function!\n",__func__,__LINE__);
@@ -1081,13 +1234,13 @@ fbt_getargdesc(void *arg __unused, dtrace_id_t id 
__unused, void *parg, dtrace_a
                        return;
 
                /* Skip the return type and arguments up to the one requested. 
*/
-               dp += ndx + 1;
+               dp += idwidth * (ndx + 1);
        }
 
-       if (fbt_type_name(&lc, *dp, desc->dtargd_native, 
sizeof(desc->dtargd_native)) > 0)
+       type = 0;
+       memcpy(&type, dp, idwidth);
+       if (fbt_type_name(&lc, type, desc->dtargd_native, 
sizeof(desc->dtargd_native)) > 0)
                desc->dtargd_ndx = ndx;
-
-       return;
 }
 
 static int

Reply via email to