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