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: }