[BACK]Return to parse.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ctfconv

Annotation of src/usr.bin/ctfconv/parse.c, Revision 1.2

1.2     ! jasper      1: /*     $OpenBSD$ */
        !             2:
1.1       mpi         3: /*
                      4:  * Copyright (c) 2016-2017 Martin Pieuchot
                      5:  * Copyright (c) 2016 Jasper Lievisse Adriaanse <jasper@openbsd.org>
                      6:  *
                      7:  * Permission to use, copy, modify, and distribute this software for any
                      8:  * purpose with or without fee is hereby granted, provided that the above
                      9:  * copyright notice and this permission notice appear in all copies.
                     10:  *
                     11:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:  */
                     19:
                     20: /*
                     21:  * DWARF to IT (internal type) representation parser.
                     22:  */
                     23:
                     24: #include <sys/param.h>
                     25: #include <sys/types.h>
                     26: #include <sys/queue.h>
                     27: #include <sys/tree.h>
                     28: #include <sys/ctf.h>
                     29:
                     30: #include <assert.h>
                     31: #include <err.h>
                     32: #include <stdlib.h>
                     33: #include <string.h>
                     34:
                     35: #include "itype.h"
                     36: #include "xmalloc.h"
                     37: #include "dwarf.h"
                     38: #include "dw.h"
                     39: #include "pool.h"
                     40:
                     41: #ifdef DEBUG
                     42: #include <stdio.h>
                     43: #endif
                     44:
                     45: #ifndef NOPOOL
                     46: struct pool it_pool, im_pool, ir_pool;
                     47: #endif /* NOPOOL */
                     48:
                     49: #define DPRINTF(x...)  do { /*printf(x)*/ } while (0)
                     50:
                     51: #define VOID_OFFSET    1       /* Fake offset for generating "void" type. */
                     52:
                     53: /*
                     54:  * Tree used to resolve per-CU types based on their offset in
                     55:  * the abbrev section.
                     56:  */
                     57: RB_HEAD(ioff_tree, itype);
                     58:
                     59: /*
                     60:  * Per-type trees used to merge exsiting types with the ones of
                     61:  * a newly parsed CU.
                     62:  */
                     63: RB_HEAD(itype_tree, itype)      itypet[CTF_K_MAX];
                     64:
                     65: /*
                     66:  * Tree of symbols used to build a list matching the order of
                     67:  * the ELF symbol table.
                     68:  */
                     69: struct isymb_tree       isymbt;
                     70:
                     71: struct itype           *void_it;
                     72: uint16_t                tidx, fidx, oidx;      /* type, func & object IDs */
                     73: uint16_t                long_tidx;             /* index of "long", for array */
                     74:
                     75:
                     76: void            cu_stat(void);
                     77: void            cu_parse(struct dwcu *, struct itype_queue *,
                     78:                     struct ioff_tree *);
                     79: void            cu_resolve(struct dwcu *, struct itype_queue *,
                     80:                     struct ioff_tree *);
                     81: void            cu_reference(struct dwcu *, struct itype_queue *);
                     82: void            cu_merge(struct dwcu *, struct itype_queue *);
                     83:
                     84: struct itype   *parse_base(struct dwdie *, size_t);
                     85: struct itype   *parse_refers(struct dwdie *, size_t, int);
                     86: struct itype   *parse_array(struct dwdie *, size_t);
                     87: struct itype   *parse_enum(struct dwdie *, size_t);
                     88: struct itype   *parse_struct(struct dwdie *, size_t, int, size_t);
                     89: struct itype   *parse_function(struct dwdie *, size_t);
                     90: struct itype   *parse_funcptr(struct dwdie *, size_t);
                     91: struct itype   *parse_variable(struct dwdie *, size_t);
                     92:
                     93: void            subparse_subrange(struct dwdie *, size_t, struct itype *);
                     94: void            subparse_enumerator(struct dwdie *, size_t, struct itype *);
                     95: void            subparse_member(struct dwdie *, size_t, struct itype *, size_t);
                     96: void            subparse_arguments(struct dwdie *, size_t, struct itype *);
                     97:
                     98: size_t          dav2val(struct dwaval *, size_t);
                     99: const char     *dav2str(struct dwaval *);
                    100: const char     *enc2name(unsigned short);
                    101:
                    102: struct itype   *it_new(uint64_t, size_t, const char *, uint32_t, uint16_t,
                    103:                     uint64_t, uint16_t, unsigned int);
                    104: void            it_reference(struct itype *);
                    105: void            it_free(struct itype *);
                    106: int             it_cmp(struct itype *, struct itype *);
                    107: int             it_name_cmp(struct itype *, struct itype *);
                    108: int             it_off_cmp(struct itype *, struct itype *);
                    109: void            ir_add(struct itype *, struct itype *);
                    110: void            ir_purge(struct itype *);
                    111: struct imember *im_new(const char *, size_t, size_t);
                    112:
                    113: RB_GENERATE(itype_tree, itype, it_node, it_cmp);
                    114: RB_GENERATE(isymb_tree, itype, it_node, it_name_cmp);
                    115: RB_GENERATE(ioff_tree, itype, it_node, it_off_cmp);
                    116:
                    117: /*
                    118:  * Construct a list of internal type and functions based on DWARF
                    119:  * INFO and ABBREV sections.
                    120:  *
                    121:  * Multiple CUs are supported.
                    122:  */
                    123: void
                    124: dwarf_parse(const char *infobuf, size_t infolen, const char *abbuf,
                    125:     size_t ablen)
                    126: {
                    127:        struct dwbuf             info = { .buf = infobuf, .len = infolen };
                    128:        struct dwbuf             abbrev = { .buf = abbuf, .len = ablen };
                    129:        struct dwcu             *dcu = NULL;
                    130:        struct ioff_tree         cu_iofft;
                    131:        struct itype_queue       cu_itypeq;
                    132:        struct itype            *it;
                    133:        int                      i;
                    134:
                    135:        for (i = 0; i < CTF_K_MAX; i++)
                    136:                RB_INIT(&itypet[i]);
                    137:        RB_INIT(&isymbt);
                    138:
                    139:        void_it = it_new(++tidx, VOID_OFFSET, "void", 0,
                    140:            CTF_INT_SIGNED, 0, CTF_K_INTEGER, 0);
                    141:        TAILQ_INSERT_TAIL(&itypeq, void_it, it_next);
                    142:
                    143:        while (dw_cu_parse(&info, &abbrev, infolen, &dcu) == 0) {
                    144:                TAILQ_INIT(&cu_itypeq);
                    145:                RB_INIT(&cu_iofft);
                    146:
                    147:                /* Parse this CU */
                    148:                cu_parse(dcu, &cu_itypeq, &cu_iofft);
                    149:
                    150:                /* Resolve its types. */
                    151:                cu_resolve(dcu, &cu_itypeq, &cu_iofft);
                    152:                assert(RB_EMPTY(&cu_iofft));
                    153:
                    154:                /* Mark used type as such. */
                    155:                cu_reference(dcu, &cu_itypeq);
                    156:
                    157: #ifdef DEBUG
                    158:                /* Dump statistics for current CU. */
                    159:                cu_stat();
                    160: #endif
                    161:
                    162:                /* Merge them with the common type list. */
                    163:                cu_merge(dcu, &cu_itypeq);
                    164:
                    165:                dw_dcu_free(dcu);
                    166:        }
                    167:
                    168:        /* We force array's index type to be 'long', for that we need its ID. */
                    169:        RB_FOREACH(it, itype_tree, &itypet[CTF_K_INTEGER]) {
                    170:                if (it_name(it) == NULL || it->it_size != (8 * sizeof(long)))
                    171:                        continue;
                    172:
                    173:                if (strcmp(it_name(it), "unsigned") == 0) {
                    174:                        long_tidx = it->it_idx;
                    175:                        break;
                    176:                }
                    177:        }
                    178: }
                    179:
                    180: struct itype *
                    181: it_new(uint64_t index, size_t off, const char *name, uint32_t size,
                    182:     uint16_t enc, uint64_t ref, uint16_t type, unsigned int flags)
                    183: {
                    184:        struct itype *it;
                    185: #ifndef NOPOOL
                    186:        static int it_pool_inited = 0;
                    187:
                    188:        if (!it_pool_inited) {
                    189:                pool_init(&it_pool, "it", 512, sizeof(struct itype));
                    190:                pool_init(&im_pool, "im", 1024, sizeof(struct imember));
                    191:                pool_init(&ir_pool, "ir", 1024, sizeof(struct itref));
                    192:                it_pool_inited = 1;
                    193:        }
                    194: #endif
                    195:
                    196:        assert((name != NULL) || !(flags & (ITF_FUNC|ITF_OBJ)));
                    197:
                    198:        it = pmalloc(&it_pool, sizeof(*it));
                    199:        SIMPLEQ_INIT(&it->it_refs);
                    200:        TAILQ_INIT(&it->it_members);
                    201:        it->it_off = off;
                    202:        it->it_ref = ref;
                    203:        it->it_refp = NULL;
                    204:        it->it_size = size;
                    205:        it->it_nelems = 0;
                    206:        it->it_enc = enc;
                    207:        it->it_idx = index;
                    208:        it->it_type = type;
                    209:        it->it_flags = flags;
                    210:
                    211:        if (name == NULL) {
                    212:                it->it_flags |= ITF_ANON;
                    213:        } else {
                    214:                size_t n;
                    215:
                    216:                if ((n = strlcpy(it->it_name, name, ITNAME_MAX)) > ITNAME_MAX)
                    217:                        warnx("name %s too long %zd > %d", name, n, ITNAME_MAX);
                    218:        }
                    219:
                    220:        return it;
                    221: }
                    222:
                    223: struct itype *
                    224: it_dup(struct itype *it)
                    225: {
                    226:        struct imember *copim, *im;
                    227:        struct itype *copit;
                    228:
                    229:        copit = it_new(it->it_idx, it->it_off, it_name(it), it->it_size,
                    230:            it->it_enc, it->it_ref, it->it_type, it->it_flags);
                    231:
                    232:        copit->it_refp = it->it_refp;
                    233:        copit->it_nelems = it->it_nelems;
                    234:
                    235:        TAILQ_FOREACH(im, &it->it_members, im_next) {
                    236:                copim = im_new(im->im_name, im->im_ref, im->im_off);
                    237:                copim->im_refp = im->im_refp;
                    238:                TAILQ_INSERT_TAIL(&copit->it_members, copim, im_next);
                    239:        }
                    240:
                    241:        return copit;
                    242: }
                    243:
                    244: const char *
                    245: it_name(struct itype *it)
                    246: {
                    247:        if (!(it->it_flags & ITF_ANON))
                    248:                return it->it_name;
                    249:
                    250:        return NULL;
                    251: }
                    252:
                    253: void
                    254: it_reference(struct itype *it)
                    255: {
                    256:        struct imember *im;
                    257:
                    258:        if (it == NULL || it->it_flags & ITF_USED)
                    259:                return;
                    260:
                    261:        it->it_flags |= ITF_USED;
                    262:
                    263:        it_reference(it->it_refp);
                    264:        TAILQ_FOREACH(im, &it->it_members, im_next)
                    265:                it_reference(im->im_refp);
                    266: }
                    267:
                    268: void
                    269: it_free(struct itype *it)
                    270: {
                    271:        struct imember *im;
                    272:
                    273:        if (it == NULL)
                    274:                return;
                    275:
                    276:        while ((im = TAILQ_FIRST(&it->it_members)) != NULL) {
                    277:                TAILQ_REMOVE(&it->it_members, im, im_next);
                    278:                pfree(&im_pool, im);
                    279:        }
                    280:
                    281:        ir_purge(it);
                    282:        pfree(&it_pool, it);
                    283: }
                    284:
                    285: /*
                    286:  * Return 0 if ``a'' matches ``b''.
                    287:  */
                    288: int
                    289: it_cmp(struct itype *a, struct itype *b)
                    290: {
                    291:        int diff;
                    292:
                    293:        if ((diff = (a->it_type - b->it_type)) != 0)
                    294:                return diff;
                    295:
                    296:        if ((diff = (a->it_size - b->it_size)) != 0)
                    297:                return diff;
                    298:
                    299:        if ((diff = (a->it_nelems - b->it_nelems)) != 0)
                    300:                return diff;
                    301:
                    302:        /* Match by name */
                    303:        if (!(a->it_flags & ITF_ANON) && !(b->it_flags & ITF_ANON))
                    304:                return strcmp(it_name(a), it_name(b));
                    305:
                    306:        /* Only one of them is anonym */
                    307:        if ((a->it_flags & ITF_ANON) != (b->it_flags & ITF_ANON))
                    308:                return (a->it_flags & ITF_ANON) ? -1 : 1;
                    309:
                    310:        /* Match by reference */
                    311:        if ((a->it_refp != NULL) && (b->it_refp != NULL))
                    312:                return it_cmp(a->it_refp, b->it_refp);
                    313:
                    314:        return 1;
                    315: }
                    316:
                    317: int
                    318: it_name_cmp(struct itype *a, struct itype *b)
                    319: {
                    320:        int diff;
                    321:
                    322:        if ((diff = strcmp(it_name(a), it_name(b))) != 0)
                    323:                return diff;
                    324:
                    325:        return ((a->it_flags|ITF_MASK) - (b->it_flags|ITF_MASK));
                    326: }
                    327:
                    328: int
                    329: it_off_cmp(struct itype *a, struct itype *b)
                    330: {
                    331:        return a->it_off - b->it_off;
                    332: }
                    333:
                    334: void
                    335: ir_add(struct itype *it, struct itype *tmp)
                    336: {
                    337:        struct itref *ir;
                    338:
                    339:        SIMPLEQ_FOREACH(ir, &tmp->it_refs, ir_next) {
                    340:                if (ir->ir_itp == it)
                    341:                        return;
                    342:        }
                    343:
                    344:        ir = pmalloc(&ir_pool, sizeof(*ir));
                    345:        ir->ir_itp = it;
                    346:        SIMPLEQ_INSERT_TAIL(&tmp->it_refs, ir, ir_next);
                    347: }
                    348:
                    349: void
                    350: ir_purge(struct itype *it)
                    351: {
                    352:        struct itref *ir;
                    353:
                    354:        while ((ir = SIMPLEQ_FIRST(&it->it_refs)) != NULL) {
                    355:                SIMPLEQ_REMOVE_HEAD(&it->it_refs, ir_next);
                    356:                pfree(&ir_pool, ir);
                    357:        }
                    358: }
                    359:
                    360: struct imember *
                    361: im_new(const char *name, size_t ref, size_t off)
                    362: {
                    363:        struct imember *im;
                    364:
                    365:        im = pmalloc(&im_pool, sizeof(*im));
                    366:        im->im_ref = ref;
                    367:        im->im_off = off;
                    368:        im->im_refp = NULL;
                    369:        if (name == NULL) {
                    370:                im->im_flags = ITM_ANON;
                    371:        } else {
                    372:                size_t n;
                    373:
                    374:                n = strlcpy(im->im_name, name, ITNAME_MAX);
                    375:                if (n > ITNAME_MAX)
                    376:                        warnx("name %s too long %zd > %d", name, n,
                    377:                            ITNAME_MAX);
                    378:                im->im_flags = 0;
                    379:        }
                    380:
                    381:        return im;
                    382: }
                    383:
                    384: void
                    385: cu_stat(void)
                    386: {
                    387: #ifndef NOPOOL
                    388:        pool_dump();
                    389: #endif
                    390: }
                    391: /*
                    392:  * Worst case it's a O(n*n) resolution lookup, with ``n'' being the number
                    393:  * of elements in ``cutq''.
                    394:  */
                    395: void
                    396: cu_resolve(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot)
                    397: {
                    398:        struct itype    *it, *ref, tmp;
                    399:        struct imember  *im;
                    400:        unsigned int     toresolve;
                    401:        size_t           off = dcu->dcu_offset;
                    402:
                    403:        TAILQ_FOREACH(it, cutq, it_next) {
                    404:                if (!(it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB)))
                    405:                        continue;
                    406:
                    407:                if (it->it_flags & ITF_UNRES) {
                    408:                        tmp.it_off = it->it_ref + off;
                    409:                        ref = RB_FIND(ioff_tree, cuot, &tmp);
                    410:                        if (ref != NULL) {
                    411:                                it->it_refp = ref;
                    412:                                ir_add(it, ref);
                    413:                                it->it_flags &= ~ITF_UNRES;
                    414:                        }
                    415:                }
                    416:
                    417:                /* All members need to be resolved. */
                    418:                toresolve = it->it_nelems;
                    419:                if ((it->it_flags & ITF_UNRES_MEMB) && toresolve > 0) {
                    420:                        TAILQ_FOREACH(im, &it->it_members, im_next) {
                    421:                                tmp.it_off = im->im_ref + off;
                    422:                                ref = RB_FIND(ioff_tree, cuot, &tmp);
                    423:                                if (ref != NULL) {
                    424:                                        im->im_refp = ref;
                    425:                                        ir_add(it, ref);
                    426:                                        toresolve--;
                    427:                                }
                    428:                        }
                    429:                        if (toresolve == 0)
                    430:                                it->it_flags &= ~ITF_UNRES_MEMB;
                    431:                }
                    432: #if defined(DEBUG)
                    433:                if (it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB)) {
                    434:                        printf("0x%zx: %s type=%d unresolved 0x%llx",
                    435:                            it->it_off, it_name(it), it->it_type, it->it_ref);
                    436:                        if (toresolve)
                    437:                                printf(": %d members", toresolve);
                    438:                        TAILQ_FOREACH(im, &it->it_members, im_next) {
                    439:                                if (im->im_refp == NULL) {
                    440:                                        printf("\n%zu: %s", im->im_ref,
                    441:                                            im->im_name);
                    442:                                }
                    443:                        }
                    444:                        printf("\n");
                    445:                }
                    446: #endif /* defined(DEBUG) */
                    447:        }
                    448:
                    449:        RB_FOREACH_SAFE(it, ioff_tree, cuot, ref)
                    450:                RB_REMOVE(ioff_tree, cuot, it);
                    451: }
                    452:
                    453: void
                    454: cu_reference(struct dwcu *dcu, struct itype_queue *cutq)
                    455: {
                    456:        struct itype *it;
                    457:
                    458:        TAILQ_FOREACH(it, cutq, it_next) {
                    459:                if (it->it_flags & (ITF_OBJ|ITF_FUNC))
                    460:                        it_reference(it);
                    461:        }
                    462: }
                    463:
                    464: /*
                    465:  * Merge type representation from a CU with already known types.
                    466:  */
                    467: void
                    468: cu_merge(struct dwcu *dcu, struct itype_queue *cutq)
                    469: {
                    470:        struct itype *it, *nit, *prev, *first;
                    471:        int diff;
                    472:
                    473:        /* First ``it'' that needs a duplicate check. */
                    474:        first = TAILQ_FIRST(cutq);
                    475:        if (first == NULL)
                    476:                return;
                    477:
                    478:        TAILQ_CONCAT(&itypeq, cutq, it_next);
                    479:
                    480:        /*
                    481:         * First pass: merge types
                    482:         */
                    483:        for (it = first; it != NULL; it = nit) {
                    484:                nit = TAILQ_NEXT(it, it_next);
                    485:
                    486:                /* Move functions & variable to their own list. */
                    487:                if (it->it_flags & (ITF_FUNC|ITF_OBJ)) {
                    488:                        /*
                    489:                         * FIXME: allow static variables with the same name
                    490:                         * to be of different type.
                    491:                         */
                    492:                        if (RB_FIND(isymb_tree, &isymbt, it) == NULL)
                    493:                                RB_INSERT(isymb_tree, &isymbt, it);
                    494:                        continue;
                    495:                }
                    496:
                    497:                /* Look if we already have this type. */
                    498:                if (it->it_flags & ITF_USED)
                    499:                        prev = RB_FIND(itype_tree, &itypet[it->it_type], it);
                    500:                else
                    501:                        prev = NULL;
                    502:
                    503:                if (prev != NULL) {
                    504:                        struct itype *old = it;
                    505:                        struct itref *ir;
                    506:                        struct imember *im;
                    507:
                    508:                        /* Substitute references */
                    509:                        while ((ir = SIMPLEQ_FIRST(&old->it_refs)) != NULL) {
                    510:                                it = ir->ir_itp;
                    511:
                    512:                                SIMPLEQ_REMOVE_HEAD(&old->it_refs, ir_next);
                    513:                                pfree(&ir_pool, ir);
                    514:
                    515:                                if (it->it_refp == old)
                    516:                                        it->it_refp = prev;
                    517:
                    518:                                TAILQ_FOREACH(im, &it->it_members, im_next) {
                    519:                                        if (im->im_refp == old)
                    520:                                                im->im_refp = prev;
                    521:                                }
                    522:                        }
                    523:
                    524:                        old->it_flags &= ~ITF_USED;
                    525:                } else if (it->it_flags & ITF_USED) {
                    526:                        RB_INSERT(itype_tree, &itypet[it->it_type], it);
                    527:                }
                    528:        }
                    529:
                    530:        /*
                    531:         * Second pass: update indexes
                    532:         */
                    533:        diff = 0;
                    534:        for (it = first; it != NULL; it = nit) {
                    535:                nit = TAILQ_NEXT(it, it_next);
                    536:
                    537:                if (it->it_flags & (ITF_FUNC|ITF_OBJ))
                    538:                        continue;
                    539:
                    540:                /* Adjust indexes */
                    541:                if (it->it_flags & ITF_USED) {
                    542:                        it->it_idx -= diff;
                    543:                        continue;
                    544:                }
                    545:
                    546:                /* Remove unused */
                    547:                TAILQ_REMOVE(&itypeq, it, it_next);
                    548:                it_free(it);
                    549:                diff++;
                    550:        }
                    551:
                    552:        /* Update global index to match removed entries. */
                    553:        it = TAILQ_LAST(&itypeq, itype_queue);
                    554:        while (it->it_flags & (ITF_FUNC|ITF_OBJ))
                    555:                it = TAILQ_PREV(it, itype_queue, it_next);
                    556:
                    557:        tidx = it->it_idx;
                    558: }
                    559:
                    560: /*
                    561:  * Parse a CU.
                    562:  */
                    563: void
                    564: cu_parse(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot)
                    565: {
                    566:        struct itype *it = NULL;
                    567:        struct dwdie *die;
                    568:        size_t psz = dcu->dcu_psize;
                    569:        size_t off = dcu->dcu_offset;
                    570:
                    571:        assert(RB_EMPTY(cuot));
                    572:
                    573:        SIMPLEQ_FOREACH(die, &dcu->dcu_dies, die_next) {
                    574:                uint64_t tag = die->die_dab->dab_tag;
                    575:
                    576:                switch (tag) {
                    577:                case DW_TAG_array_type:
                    578:                        it = parse_array(die, dcu->dcu_psize);
                    579:                        break;
                    580:                case DW_TAG_enumeration_type:
                    581:                        it = parse_enum(die, dcu->dcu_psize);
                    582:                        break;
                    583:                case DW_TAG_pointer_type:
                    584:                        it = parse_refers(die, psz, CTF_K_POINTER);
                    585:                        break;
                    586:                case DW_TAG_structure_type:
                    587:                        it = parse_struct(die, psz, CTF_K_STRUCT, off);
                    588:                        if (it == NULL)
                    589:                                continue;
                    590:                        break;
                    591:                case DW_TAG_typedef:
                    592:                        it = parse_refers(die, psz, CTF_K_TYPEDEF);
                    593:                        break;
                    594:                case DW_TAG_union_type:
                    595:                        it = parse_struct(die, psz, CTF_K_UNION, off);
                    596:                        if (it == NULL)
                    597:                                continue;
                    598:                        break;
                    599:                case DW_TAG_base_type:
                    600:                        it = parse_base(die, psz);
                    601:                        break;
                    602:                case DW_TAG_const_type:
                    603:                        it = parse_refers(die, psz, CTF_K_CONST);
                    604:                        break;
                    605:                case DW_TAG_volatile_type:
                    606:                        it = parse_refers(die, psz, CTF_K_VOLATILE);
                    607:                        break;
                    608:                case DW_TAG_restrict_type:
                    609:                        it = parse_refers(die, psz, CTF_K_RESTRICT);
                    610:                        break;
                    611:                case DW_TAG_subprogram:
                    612:                        it = parse_function(die, psz);
                    613:                        if (it == NULL)
                    614:                                continue;
                    615:                        break;
                    616:                case DW_TAG_subroutine_type:
                    617:                        it = parse_funcptr(die, psz);
                    618:                        break;
                    619:                /*
                    620:                 * Children are assumed to be right after their parent in
                    621:                 * the list.  The parent parsing function takes care of
                    622:                 * parsing them.
                    623:                 */
                    624:                 case DW_TAG_member:
                    625:                         assert(it->it_type == CTF_K_STRUCT ||
                    626:                            it->it_type == CTF_K_UNION ||
                    627:                            it->it_type == CTF_K_ENUM);
                    628:                        continue;
                    629:                 case DW_TAG_subrange_type:
                    630:                        assert(it->it_type == CTF_K_ARRAY);
                    631:                        continue;
                    632:                case DW_TAG_formal_parameter:
                    633:                        /*
                    634:                         * If we skipped the second inline definition,
                    635:                         * skip its arguments.
                    636:                         */
                    637:                        if (it == NULL)
                    638:                                continue;
                    639:
                    640:                        /* See comment in subparse_arguments(). */
                    641:                        if (it->it_type == CTF_K_STRUCT ||
                    642:                            it->it_type == CTF_K_UNION ||
                    643:                            it->it_type == CTF_K_ENUM ||
                    644:                            it->it_type == CTF_K_TYPEDEF)
                    645:                                continue;
                    646:
                    647:                        if (it->it_flags & ITF_OBJ)
                    648:                                continue;
                    649:
                    650:                        assert(it->it_type == CTF_K_FUNCTION);
                    651:                        continue;
                    652:                case DW_TAG_variable:
                    653:                        it = parse_variable(die, psz);
                    654:                        /* Unnamed variables are discarded. */
                    655:                        if (it == NULL)
                    656:                                continue;
                    657:                        break;
                    658: #if 1
                    659:                case DW_TAG_lexical_block:
                    660:                case DW_TAG_inlined_subroutine:
                    661:                        continue;
                    662: #endif
                    663:                case DW_TAG_compile_unit:
                    664:                default:
                    665:                        DPRINTF("%s\n", dw_tag2name(tag));
                    666:                        continue;
                    667:                }
                    668:
                    669:                TAILQ_INSERT_TAIL(cutq, it, it_next);
                    670:                RB_INSERT(ioff_tree, cuot, it);
                    671:        }
                    672: }
                    673:
                    674: struct itype *
                    675: parse_base(struct dwdie *die, size_t psz)
                    676: {
                    677:        struct itype *it;
                    678:        struct dwaval *dav;
                    679:        uint16_t encoding, enc = 0, bits = 0;
                    680:        int type;
                    681:
                    682:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    683:                switch (dav->dav_dat->dat_attr) {
                    684:                case DW_AT_encoding:
                    685:                        enc = dav2val(dav, psz);
                    686:                        break;
                    687:                case DW_AT_byte_size:
                    688:                        bits = 8 * dav2val(dav, psz);
                    689:                        break;
                    690:                default:
                    691:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                    692:                        break;
                    693:                }
                    694:        }
                    695:
                    696:        switch (enc) {
                    697:        case DW_ATE_unsigned:
                    698:        case DW_ATE_address:
                    699:                encoding = 0;
                    700:                type = CTF_K_INTEGER;
                    701:                break;
                    702:        case DW_ATE_unsigned_char:
                    703:                encoding = CTF_INT_CHAR;
                    704:                type = CTF_K_INTEGER;
                    705:                break;
                    706:        case DW_ATE_signed:
                    707:                encoding = CTF_INT_SIGNED;
                    708:                type = CTF_K_INTEGER;
                    709:                break;
                    710:        case DW_ATE_signed_char:
                    711:                encoding = CTF_INT_SIGNED | CTF_INT_CHAR;
                    712:                type = CTF_K_INTEGER;
                    713:                break;
                    714:        case DW_ATE_boolean:
                    715:                encoding = CTF_INT_SIGNED | CTF_INT_BOOL;
                    716:                type = CTF_K_INTEGER;
                    717:                break;
                    718:        case DW_ATE_float:
                    719:                if (bits < psz)
                    720:                        encoding = CTF_FP_SINGLE;
                    721:                else if (bits == psz)
                    722:                        encoding = CTF_FP_DOUBLE;
                    723:                else
                    724:                        encoding = CTF_FP_LDOUBLE;
                    725:                type = CTF_K_FLOAT;
                    726:                break;
                    727:        case DW_ATE_complex_float:
                    728:                if (bits < psz)
                    729:                        encoding = CTF_FP_CPLX;
                    730:                else if (bits == psz)
                    731:                        encoding = CTF_FP_DCPLX;
                    732:                else
                    733:                        encoding = CTF_FP_LDCPLX;
                    734:                type = CTF_K_FLOAT;
                    735:                break;
                    736:        case DW_ATE_imaginary_float:
                    737:                if (bits < psz)
                    738:                        encoding = CTF_FP_IMAGRY;
                    739:                else if (bits == psz)
                    740:                        encoding = CTF_FP_DIMAGRY;
                    741:                else
                    742:                        encoding = CTF_FP_LDIMAGRY;
                    743:                type = CTF_K_FLOAT;
                    744:                break;
                    745:        default:
                    746:                DPRINTF("unknown encoding: %d\n", enc);
                    747:                return (NULL);
                    748:        }
                    749:
                    750:        it = it_new(++tidx, die->die_offset, enc2name(enc), bits,
                    751:            encoding, 0, type, 0);
                    752:
                    753:        return it;
                    754: }
                    755:
                    756: struct itype *
                    757: parse_refers(struct dwdie *die, size_t psz, int type)
                    758: {
                    759:        struct itype *it;
                    760:        struct dwaval *dav;
                    761:        const char *name = NULL;
                    762:        size_t ref = 0, size = 0;
                    763:
                    764:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    765:                switch (dav->dav_dat->dat_attr) {
                    766:                case DW_AT_name:
                    767:                        name = dav2str(dav);
                    768:                        break;
                    769:                case DW_AT_type:
                    770:                        ref = dav2val(dav, psz);
                    771:                        break;
                    772:                case DW_AT_byte_size:
                    773:                        size = dav2val(dav, psz);
                    774:                        assert(size < UINT_MAX);
                    775:                        break;
                    776:                default:
                    777:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                    778:                        break;
                    779:                }
                    780:        }
                    781:
                    782:        it = it_new(++tidx, die->die_offset, name, size, 0, ref, type,
                    783:            ITF_UNRES);
                    784:
                    785:        if (it->it_ref == 0 && (it->it_size == sizeof(void *) ||
                    786:            type == CTF_K_CONST || type == CTF_K_VOLATILE ||
                    787:            type == CTF_K_POINTER)) {
                    788:                /* Work around GCC/clang not emiting a type for void */
                    789:                it->it_flags &= ~ITF_UNRES;
                    790:                it->it_ref = VOID_OFFSET;
                    791:                it->it_refp = void_it;
                    792:        }
                    793:
                    794:        return it;
                    795: }
                    796:
                    797: struct itype *
                    798: parse_array(struct dwdie *die, size_t psz)
                    799: {
                    800:        struct itype *it;
                    801:        struct dwaval *dav;
                    802:        const char *name = NULL;
                    803:        size_t ref = 0;
                    804:
                    805:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    806:                switch (dav->dav_dat->dat_attr) {
                    807:                case DW_AT_name:
                    808:                        name = dav2str(dav);
                    809:                        break;
                    810:                case DW_AT_type:
                    811:                        ref = dav2val(dav, psz);
                    812:                        break;
                    813:                default:
                    814:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                    815:                        break;
                    816:                }
                    817:        }
                    818:
                    819:        it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_ARRAY,
                    820:            ITF_UNRES);
                    821:
                    822:        subparse_subrange(die, psz, it);
                    823:
                    824:        return it;
                    825: }
                    826:
                    827: struct itype *
                    828: parse_enum(struct dwdie *die, size_t psz)
                    829: {
                    830:        struct itype *it;
                    831:        struct dwaval *dav;
                    832:        const char *name = NULL;
                    833:        size_t size = 0;
                    834:
                    835:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    836:                switch (dav->dav_dat->dat_attr) {
                    837:                case DW_AT_byte_size:
                    838:                        size = dav2val(dav, psz);
                    839:                        assert(size < UINT_MAX);
                    840:                        break;
                    841:                case DW_AT_name:
                    842:                        name = dav2str(dav);
                    843:                        break;
                    844:                default:
                    845:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                    846:                        break;
                    847:                }
                    848:        }
                    849:
                    850:        it = it_new(++tidx, die->die_offset, name, size, 0, 0, CTF_K_ENUM, 0);
                    851:
                    852:        subparse_enumerator(die, psz, it);
                    853:
                    854:        return it;
                    855: }
                    856:
                    857: void
                    858: subparse_subrange(struct dwdie *die, size_t psz, struct itype *it)
                    859: {
                    860:        struct dwaval *dav;
                    861:
                    862:        assert(it->it_type == CTF_K_ARRAY);
                    863:
                    864:        if (die->die_dab->dab_children == DW_CHILDREN_no)
                    865:                return;
                    866:
                    867:        /*
                    868:         * This loop assumes that the children of a DIE are just
                    869:         * after it on the list.
                    870:         */
                    871:        while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
                    872:                uint64_t tag = die->die_dab->dab_tag;
                    873:                size_t nelems = 0;
                    874:
                    875:                if (tag != DW_TAG_subrange_type)
                    876:                        break;
                    877:
                    878:                SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    879:                        switch (dav->dav_dat->dat_attr) {
                    880:                        case DW_AT_count:
                    881:                                nelems = dav2val(dav, psz);
                    882:                                break;
                    883:                        case DW_AT_upper_bound:
                    884:                                nelems = dav2val(dav, psz) + 1;
                    885:                                break;
                    886:                        default:
                    887:                                DPRINTF("%s\n",
                    888:                                    dw_at2name(dav->dav_dat->dat_attr));
                    889:                                break;
                    890:                        }
                    891:                }
                    892:
                    893:                assert(nelems < UINT_MAX);
                    894:                it->it_nelems = nelems;
                    895:        }
                    896: }
                    897:
                    898: void
                    899: subparse_enumerator(struct dwdie *die, size_t psz, struct itype *it)
                    900: {
                    901:        struct imember *im;
                    902:        struct dwaval *dav;
                    903:
                    904:        assert(it->it_type == CTF_K_ENUM);
                    905:
                    906:        if (die->die_dab->dab_children == DW_CHILDREN_no)
                    907:                return;
                    908:
                    909:        /*
                    910:         * This loop assumes that the children of a DIE are just
                    911:         * after it on the list.
                    912:         */
                    913:        while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
                    914:                uint64_t tag = die->die_dab->dab_tag;
                    915:                size_t val = 0;
                    916:                const char *name = NULL;
                    917:
                    918:                if (tag != DW_TAG_enumerator)
                    919:                        break;
                    920:
                    921:                SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    922:                        switch (dav->dav_dat->dat_attr) {
                    923:                        case DW_AT_name:
                    924:                                name = dav2str(dav);
                    925:                                break;
                    926:                        case DW_AT_const_value:
                    927:                                val = dav2val(dav, psz);
                    928:                                break;
                    929:                        default:
                    930:                                DPRINTF("%s\n",
                    931:                                    dw_at2name(dav->dav_dat->dat_attr));
                    932:                                break;
                    933:                        }
                    934:                }
                    935:
                    936:                if (name == NULL) {
                    937:                        warnx("%s with anon member", it_name(it));
                    938:                        continue;
                    939:                }
                    940:
                    941:                im = im_new(name, val, 0);
                    942:                assert(it->it_nelems < UINT_MAX);
                    943:                it->it_nelems++;
                    944:                TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
                    945:        }
                    946: }
                    947:
                    948: struct itype *
                    949: parse_struct(struct dwdie *die, size_t psz, int type, size_t off)
                    950: {
                    951:        struct itype *it = NULL;
                    952:        struct dwaval *dav;
                    953:        const char *name = NULL;
                    954:        size_t size = 0;
                    955:
                    956:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                    957:                switch (dav->dav_dat->dat_attr) {
                    958:                case DW_AT_byte_size:
                    959:                        size = dav2val(dav, psz);
                    960:                        assert(size < UINT_MAX);
                    961:                        break;
                    962:                case DW_AT_name:
                    963:                        name = dav2str(dav);
                    964:                        break;
                    965:                default:
                    966:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                    967:                        break;
                    968:                }
                    969:        }
                    970:
                    971:        it = it_new(++tidx, die->die_offset, name, size, 0, 0, type, 0);
                    972:
                    973:        subparse_member(die, psz, it, off);
                    974:
                    975:        return it;
                    976: }
                    977:
                    978: void
                    979: subparse_member(struct dwdie *die, size_t psz, struct itype *it, size_t offset)
                    980: {
                    981:        struct imember *im;
                    982:        struct dwaval *dav;
                    983:        const char *name;
                    984:        size_t off = 0, ref = 0, bits = 0;
                    985:        uint8_t lvl = die->die_lvl;
                    986:
                    987:        assert(it->it_type == CTF_K_STRUCT || it->it_type == CTF_K_UNION);
                    988:
                    989:        if (die->die_dab->dab_children == DW_CHILDREN_no)
                    990:                return;
                    991:
                    992:        /*
                    993:         * This loop assumes that the children of a DIE are just
                    994:         * after it on the list.
                    995:         */
                    996:        while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
                    997:                int64_t tag = die->die_dab->dab_tag;
                    998:
                    999:                name = NULL;
                   1000:                if (die->die_lvl <= lvl)
                   1001:                        break;
                   1002:
                   1003:                /* Skip members of members */
                   1004:                if (die->die_lvl > lvl + 1)
                   1005:                        continue;
                   1006:
                   1007:                it->it_flags |= ITF_UNRES_MEMB;
                   1008:
                   1009:                SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                   1010:                        switch (dav->dav_dat->dat_attr) {
                   1011:                        case DW_AT_name:
                   1012:                                name = dav2str(dav);
                   1013:                                break;
                   1014:                        case DW_AT_type:
                   1015:                                ref = dav2val(dav, psz);
                   1016:                                break;
                   1017:                        case DW_AT_data_member_location:
                   1018:                                off = 8 * dav2val(dav, psz);
                   1019:                                break;
                   1020:                        case DW_AT_bit_size:
                   1021:                                bits = dav2val(dav, psz);
                   1022:                                assert(bits < USHRT_MAX);
                   1023:                                break;
                   1024:                        default:
                   1025:                                DPRINTF("%s\n",
                   1026:                                    dw_at2name(dav->dav_dat->dat_attr));
                   1027:                                break;
                   1028:                        }
                   1029:                }
                   1030:
                   1031:                /*
                   1032:                 * When a structure is declared inside an union, we
                   1033:                 * have to generate a reference to make the resolver
                   1034:                 * happy.
                   1035:                 */
                   1036:                if ((ref == 0) && (tag == DW_TAG_structure_type))
                   1037:                        ref = die->die_offset - offset;
                   1038:
                   1039:                im = im_new(name, ref, off);
                   1040:                assert(it->it_nelems < UINT_MAX);
                   1041:                it->it_nelems++;
                   1042:                TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
                   1043:        }
                   1044: }
                   1045:
                   1046:
                   1047: void
                   1048: subparse_arguments(struct dwdie *die, size_t psz, struct itype *it)
                   1049: {
                   1050:        struct imember *im;
                   1051:        struct dwaval *dav;
                   1052:        size_t ref = 0;
                   1053:
                   1054:        assert(it->it_type == CTF_K_FUNCTION);
                   1055:
                   1056:        if (die->die_dab->dab_children == DW_CHILDREN_no)
                   1057:                return;
                   1058:
                   1059:        /*
                   1060:         * This loop assumes that the children of a DIE are after it
                   1061:         * on the list.
                   1062:         */
                   1063:        while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
                   1064:                uint64_t tag = die->die_dab->dab_tag;
                   1065:
                   1066:                if (tag == DW_TAG_unspecified_parameters) {
                   1067:                        it->it_flags |= ITF_VARARGS;
                   1068:                        continue;
                   1069:                }
                   1070:
                   1071:                /*
                   1072:                 * Nested declaration.
                   1073:                 *
                   1074:                 * This matches the case where a ``struct'', ``union'',
                   1075:                 * ``enum'' or ``typedef'' is first declared "inside" a
                   1076:                 * function declaration.
                   1077:                 */
                   1078:                if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type ||
                   1079:                    tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef)
                   1080:                        continue;
                   1081:
                   1082:                if (tag != DW_TAG_formal_parameter)
                   1083:                        break;
                   1084:
                   1085:                it->it_flags |= ITF_UNRES_MEMB;
                   1086:
                   1087:                SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                   1088:                        switch (dav->dav_dat->dat_attr) {
                   1089:                        case DW_AT_type:
                   1090:                                ref = dav2val(dav, psz);
                   1091:                                break;
                   1092:                        default:
                   1093:                                DPRINTF("%s\n",
                   1094:                                    dw_at2name(dav->dav_dat->dat_attr));
                   1095:                                break;
                   1096:                        }
                   1097:                }
                   1098:
                   1099:                im = im_new(NULL, ref, 0);
                   1100:                assert(it->it_nelems < UINT_MAX);
                   1101:                it->it_nelems++;
                   1102:                TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
                   1103:        }
                   1104: }
                   1105:
                   1106: struct itype *
                   1107: parse_function(struct dwdie *die, size_t psz)
                   1108: {
                   1109:        struct itype *it;
                   1110:        struct dwaval *dav;
                   1111:        const char *name = NULL;
                   1112:        size_t ref = 0;
                   1113:
                   1114:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                   1115:                switch (dav->dav_dat->dat_attr) {
                   1116:                case DW_AT_name:
                   1117:                        name = dav2str(dav);
                   1118:                        break;
                   1119:                case DW_AT_type:
                   1120:                        ref = dav2val(dav, psz);
                   1121:                        break;
                   1122:                case DW_AT_abstract_origin:
                   1123:                        /*
                   1124:                         * Skip second empty definition for inline
                   1125:                         * functions.
                   1126:                         */
                   1127:                        return NULL;
                   1128:                default:
                   1129:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                   1130:                        break;
                   1131:                }
                   1132:        }
                   1133:
                   1134:        /*
                   1135:         * Work around for clang 4.0 generating DW_TAG_subprogram without
                   1136:         * any attribute.
                   1137:         */
                   1138:        if (name == NULL)
                   1139:                return NULL;
                   1140:
                   1141:        it = it_new(++fidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION,
                   1142:            ITF_UNRES|ITF_FUNC);
                   1143:
                   1144:        subparse_arguments(die, psz, it);
                   1145:
                   1146:        if (it->it_ref == 0) {
                   1147:                /* Work around GCC not emiting a type for void */
                   1148:                it->it_flags &= ~ITF_UNRES;
                   1149:                it->it_ref = VOID_OFFSET;
                   1150:                it->it_refp = void_it;
                   1151:        }
                   1152:
                   1153:        return it;
                   1154: }
                   1155:
                   1156: struct itype *
                   1157: parse_funcptr(struct dwdie *die, size_t psz)
                   1158: {
                   1159:        struct itype *it;
                   1160:        struct dwaval *dav;
                   1161:        const char *name = NULL;
                   1162:        size_t ref = 0;
                   1163:
                   1164:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                   1165:                switch (dav->dav_dat->dat_attr) {
                   1166:                case DW_AT_name:
                   1167:                        name = dav2str(dav);
                   1168:                        break;
                   1169:                case DW_AT_type:
                   1170:                        ref = dav2val(dav, psz);
                   1171:                        break;
                   1172:                default:
                   1173:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                   1174:                        break;
                   1175:                }
                   1176:        }
                   1177:
                   1178:        it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION,
                   1179:            ITF_UNRES);
                   1180:
                   1181:        subparse_arguments(die, psz, it);
                   1182:
                   1183:        if (it->it_ref == 0) {
                   1184:                /* Work around GCC not emiting a type for void */
                   1185:                it->it_flags &= ~ITF_UNRES;
                   1186:                it->it_ref = VOID_OFFSET;
                   1187:                it->it_refp = void_it;
                   1188:        }
                   1189:
                   1190:        return it;
                   1191: }
                   1192:
                   1193: struct itype *
                   1194: parse_variable(struct dwdie *die, size_t psz)
                   1195: {
                   1196:        struct itype *it = NULL;
                   1197:        struct dwaval *dav;
                   1198:        const char *name = NULL;
                   1199:        size_t ref = 0;
                   1200:        int declaration = 0;
                   1201:
                   1202:        SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
                   1203:                switch (dav->dav_dat->dat_attr) {
                   1204:                case DW_AT_declaration:
                   1205:                        declaration = dav2val(dav, psz);
                   1206:                        break;
                   1207:                case DW_AT_name:
                   1208:                        name = dav2str(dav);
                   1209:                        break;
                   1210:                case DW_AT_type:
                   1211:                        ref = dav2val(dav, psz);
                   1212:                        break;
                   1213:                default:
                   1214:                        DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
                   1215:                        break;
                   1216:                }
                   1217:        }
                   1218:
                   1219:
                   1220:        if (!declaration && name != NULL) {
                   1221:                it = it_new(++oidx, die->die_offset, name, 0, 0, ref, 0,
                   1222:                    ITF_UNRES|ITF_OBJ);
                   1223:        }
                   1224:
                   1225:        return it;
                   1226: }
                   1227:
                   1228: size_t
                   1229: dav2val(struct dwaval *dav, size_t psz)
                   1230: {
                   1231:        uint64_t val = (uint64_t)-1;
                   1232:
                   1233:        switch (dav->dav_dat->dat_form) {
                   1234:        case DW_FORM_addr:
                   1235:        case DW_FORM_ref_addr:
                   1236:                if (psz == sizeof(uint32_t))
                   1237:                        val = dav->dav_u32;
                   1238:                else
                   1239:                        val = dav->dav_u64;
                   1240:                break;
                   1241:        case DW_FORM_block1:
                   1242:        case DW_FORM_block2:
                   1243:        case DW_FORM_block4:
                   1244:        case DW_FORM_block:
                   1245:                dw_loc_parse(&dav->dav_buf, NULL, &val, NULL);
                   1246:                break;
                   1247:        case DW_FORM_flag:
                   1248:        case DW_FORM_data1:
                   1249:        case DW_FORM_ref1:
                   1250:                val = dav->dav_u8;
                   1251:                break;
                   1252:        case DW_FORM_data2:
                   1253:        case DW_FORM_ref2:
                   1254:                val = dav->dav_u16;
                   1255:                break;
                   1256:        case DW_FORM_data4:
                   1257:        case DW_FORM_ref4:
                   1258:                val = dav->dav_u32;
                   1259:                break;
                   1260:        case DW_FORM_sdata:
                   1261:        case DW_FORM_data8:
                   1262:        case DW_FORM_ref8:
                   1263:                val = dav->dav_u64;
                   1264:                break;
                   1265:        case DW_FORM_strp:
                   1266:                val = dav->dav_u32;
                   1267:                break;
                   1268:        case DW_FORM_flag_present:
                   1269:                val = 1;
                   1270:                break;
                   1271:        default:
                   1272:                break;
                   1273:        }
                   1274:
                   1275:        return val;
                   1276: }
                   1277:
                   1278: const char *
                   1279: dav2str(struct dwaval *dav)
                   1280: {
                   1281:        const char *str = NULL;
                   1282:        extern const char *dstrbuf;
                   1283:
                   1284:        switch (dav->dav_dat->dat_form) {
                   1285:        case DW_FORM_string:
                   1286:                str = dav->dav_str;
                   1287:                break;
                   1288:        case DW_FORM_strp:
                   1289:                str = dstrbuf + dav->dav_u32;
                   1290:                break;
                   1291:        default:
                   1292:                break;
                   1293:        }
                   1294:
                   1295:        return str;
                   1296: }
                   1297:
                   1298: const char *
                   1299: enc2name(unsigned short enc)
                   1300: {
                   1301:        static const char *enc_name[] = { "address", "boolean", "complex float",
                   1302:            "float", "signed", "char", "unsigned", "unsigned char",
                   1303:            "imaginary float", "packed decimal", "numeric string", "edited",
                   1304:            "signed fixed", "unsigned fixed", "decimal float" };
                   1305:
                   1306:        if (enc > 0 && enc <= nitems(enc_name))
                   1307:                return enc_name[enc - 1];
                   1308:
                   1309:        return "invalid";
                   1310: }