xref: /openbsd-src/usr.bin/ctfconv/parse.c (revision f763167468dba5339ed4b14b7ecaca2a397ab0f6)
1 /*	$OpenBSD: parse.c,v 1.7 2017/09/24 09:14:25 jsg Exp $ */
2 
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>	/* nitems() */
25 #include <sys/queue.h>
26 #include <sys/tree.h>
27 #include <sys/ctf.h>
28 
29 #include <assert.h>
30 #include <limits.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_name(im), 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 = IMF_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 const char *
385 im_name(struct imember *im)
386 {
387 	if (!(im->im_flags & IMF_ANON))
388 		return im->im_name;
389 
390 	return NULL;
391 }
392 
393 void
394 cu_stat(void)
395 {
396 #ifndef NOPOOL
397 	pool_dump();
398 #endif
399 }
400 /*
401  * Worst case it's a O(n*n) resolution lookup, with ``n'' being the number
402  * of elements in ``cutq''.
403  */
404 void
405 cu_resolve(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot)
406 {
407 	struct itype	*it, *ref, tmp;
408 	struct imember	*im;
409 	unsigned int	 toresolve;
410 	size_t		 off = dcu->dcu_offset;
411 
412 	TAILQ_FOREACH(it, cutq, it_next) {
413 		if (!(it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB)))
414 			continue;
415 
416 		if (it->it_flags & ITF_UNRES) {
417 			tmp.it_off = it->it_ref + off;
418 			ref = RB_FIND(ioff_tree, cuot, &tmp);
419 			if (ref != NULL) {
420 				it->it_refp = ref;
421 				ir_add(it, ref);
422 				it->it_flags &= ~ITF_UNRES;
423 			}
424 		}
425 
426 		/* All members need to be resolved. */
427 		toresolve = it->it_nelems;
428 		if ((it->it_flags & ITF_UNRES_MEMB) && toresolve > 0) {
429 			TAILQ_FOREACH(im, &it->it_members, im_next) {
430 				tmp.it_off = im->im_ref + off;
431 				ref = RB_FIND(ioff_tree, cuot, &tmp);
432 				if (ref != NULL) {
433 					im->im_refp = ref;
434 					ir_add(it, ref);
435 					toresolve--;
436 				}
437 			}
438 			if (toresolve == 0)
439 				it->it_flags &= ~ITF_UNRES_MEMB;
440 		}
441 #if defined(DEBUG)
442 		if (it->it_flags & (ITF_UNRES|ITF_UNRES_MEMB)) {
443 			printf("0x%zx: %s type=%d unresolved 0x%llx",
444 			    it->it_off, it_name(it), it->it_type, it->it_ref);
445 			if (toresolve)
446 				printf(": %d members", toresolve);
447 			TAILQ_FOREACH(im, &it->it_members, im_next) {
448 				if (im->im_refp != NULL)
449 					continue;
450 				printf("\n%zu: %s", im->im_ref, im_name(im));
451 			}
452 			printf("\n");
453 		}
454 #endif /* defined(DEBUG) */
455 	}
456 
457 	RB_FOREACH_SAFE(it, ioff_tree, cuot, ref)
458 		RB_REMOVE(ioff_tree, cuot, it);
459 }
460 
461 void
462 cu_reference(struct dwcu *dcu, struct itype_queue *cutq)
463 {
464 	struct itype *it;
465 
466 	TAILQ_FOREACH(it, cutq, it_next) {
467 		if (it->it_flags & (ITF_OBJ|ITF_FUNC))
468 			it_reference(it);
469 	}
470 }
471 
472 /*
473  * Merge type representation from a CU with already known types.
474  */
475 void
476 cu_merge(struct dwcu *dcu, struct itype_queue *cutq)
477 {
478 	struct itype *it, *nit, *prev, *first;
479 	int diff;
480 
481 	/* First ``it'' that needs a duplicate check. */
482 	first = TAILQ_FIRST(cutq);
483 	if (first == NULL)
484 		return;
485 
486 	TAILQ_CONCAT(&itypeq, cutq, it_next);
487 
488 	/*
489 	 * First pass: merge types
490 	 */
491 	for (it = first; it != NULL; it = nit) {
492 		nit = TAILQ_NEXT(it, it_next);
493 
494 		/* Move functions & variable to their own list. */
495 		if (it->it_flags & (ITF_FUNC|ITF_OBJ)) {
496 			/*
497 			 * FIXME: allow static variables with the same name
498 			 * to be of different type.
499 			 */
500 			if (RB_FIND(isymb_tree, &isymbt, it) == NULL)
501 				RB_INSERT(isymb_tree, &isymbt, it);
502 			continue;
503 		}
504 
505 		/* Look if we already have this type. */
506 		if (it->it_flags & ITF_USED)
507 			prev = RB_FIND(itype_tree, &itypet[it->it_type], it);
508 		else
509 			prev = NULL;
510 
511 		if (prev != NULL) {
512 			struct itype *old = it;
513 			struct itref *ir;
514 			struct imember *im;
515 
516 			/* Substitute references */
517 			while ((ir = SIMPLEQ_FIRST(&old->it_refs)) != NULL) {
518 				it = ir->ir_itp;
519 
520 				SIMPLEQ_REMOVE_HEAD(&old->it_refs, ir_next);
521 				pfree(&ir_pool, ir);
522 
523 				if (it->it_refp == old)
524 					it->it_refp = prev;
525 
526 				TAILQ_FOREACH(im, &it->it_members, im_next) {
527 					if (im->im_refp == old)
528 						im->im_refp = prev;
529 				}
530 			}
531 
532 			old->it_flags &= ~ITF_USED;
533 		} else if (it->it_flags & ITF_USED) {
534 			RB_INSERT(itype_tree, &itypet[it->it_type], it);
535 		}
536 	}
537 
538 	/*
539 	 * Second pass: update indexes
540 	 */
541 	diff = 0;
542 	for (it = first; it != NULL; it = nit) {
543 		nit = TAILQ_NEXT(it, it_next);
544 
545 		if (it->it_flags & (ITF_FUNC|ITF_OBJ))
546 			continue;
547 
548 		/* Adjust indexes */
549 		if (it->it_flags & ITF_USED) {
550 			it->it_idx -= diff;
551 			continue;
552 		}
553 
554 		/* Remove unused */
555 		TAILQ_REMOVE(&itypeq, it, it_next);
556 		it_free(it);
557 		diff++;
558 	}
559 
560 	/* Update global index to match removed entries. */
561 	it = TAILQ_LAST(&itypeq, itype_queue);
562 	while (it->it_flags & (ITF_FUNC|ITF_OBJ))
563 		it = TAILQ_PREV(it, itype_queue, it_next);
564 
565 	tidx = it->it_idx;
566 }
567 
568 /*
569  * Parse a CU.
570  */
571 void
572 cu_parse(struct dwcu *dcu, struct itype_queue *cutq, struct ioff_tree *cuot)
573 {
574 	struct itype *it = NULL;
575 	struct dwdie *die;
576 	size_t psz = dcu->dcu_psize;
577 	size_t off = dcu->dcu_offset;
578 
579 	assert(RB_EMPTY(cuot));
580 
581 	SIMPLEQ_FOREACH(die, &dcu->dcu_dies, die_next) {
582 		uint64_t tag = die->die_dab->dab_tag;
583 
584 		switch (tag) {
585 		case DW_TAG_array_type:
586 			it = parse_array(die, dcu->dcu_psize);
587 			break;
588 		case DW_TAG_enumeration_type:
589 			it = parse_enum(die, dcu->dcu_psize);
590 			break;
591 		case DW_TAG_pointer_type:
592 			it = parse_refers(die, psz, CTF_K_POINTER);
593 			break;
594 		case DW_TAG_structure_type:
595 			it = parse_struct(die, psz, CTF_K_STRUCT, off);
596 			if (it == NULL)
597 				continue;
598 			break;
599 		case DW_TAG_typedef:
600 			it = parse_refers(die, psz, CTF_K_TYPEDEF);
601 			break;
602 		case DW_TAG_union_type:
603 			it = parse_struct(die, psz, CTF_K_UNION, off);
604 			if (it == NULL)
605 				continue;
606 			break;
607 		case DW_TAG_base_type:
608 			it = parse_base(die, psz);
609 			if (it == NULL)
610 				continue;
611 			break;
612 		case DW_TAG_const_type:
613 			it = parse_refers(die, psz, CTF_K_CONST);
614 			break;
615 		case DW_TAG_volatile_type:
616 			it = parse_refers(die, psz, CTF_K_VOLATILE);
617 			break;
618 		case DW_TAG_restrict_type:
619 			it = parse_refers(die, psz, CTF_K_RESTRICT);
620 			break;
621 		case DW_TAG_subprogram:
622 			it = parse_function(die, psz);
623 			if (it == NULL)
624 				continue;
625 			break;
626 		case DW_TAG_subroutine_type:
627 			it = parse_funcptr(die, psz);
628 			break;
629 		/*
630 		 * Children are assumed to be right after their parent in
631 		 * the list.  The parent parsing function takes care of
632 		 * parsing them.
633 		 */
634 		 case DW_TAG_member:
635 			 assert(it->it_type == CTF_K_STRUCT ||
636 			    it->it_type == CTF_K_UNION ||
637 			    it->it_type == CTF_K_ENUM);
638 			continue;
639 		 case DW_TAG_subrange_type:
640 			assert(it->it_type == CTF_K_ARRAY);
641 			continue;
642 		case DW_TAG_formal_parameter:
643 			/*
644 			 * If we skipped the second inline definition,
645 			 * skip its arguments.
646 			 */
647 			if (it == NULL)
648 				continue;
649 
650 			/* See comment in subparse_arguments(). */
651 			if (it->it_type == CTF_K_STRUCT ||
652 			    it->it_type == CTF_K_UNION ||
653 			    it->it_type == CTF_K_ENUM ||
654 			    it->it_type == CTF_K_TYPEDEF)
655 				continue;
656 
657 			if (it->it_flags & ITF_OBJ)
658 				continue;
659 
660 			assert(it->it_type == CTF_K_FUNCTION);
661 			continue;
662 		case DW_TAG_variable:
663 			it = parse_variable(die, psz);
664 			/* Unnamed variables are discarded. */
665 			if (it == NULL)
666 				continue;
667 			break;
668 #if 1
669 		case DW_TAG_lexical_block:
670 		case DW_TAG_inlined_subroutine:
671 			continue;
672 #endif
673 		case DW_TAG_compile_unit:
674 		default:
675 			DPRINTF("%s\n", dw_tag2name(tag));
676 			continue;
677 		}
678 
679 		TAILQ_INSERT_TAIL(cutq, it, it_next);
680 		RB_INSERT(ioff_tree, cuot, it);
681 	}
682 }
683 
684 struct itype *
685 parse_base(struct dwdie *die, size_t psz)
686 {
687 	struct itype *it;
688 	struct dwaval *dav;
689 	uint16_t encoding, enc = 0, bits = 0;
690 	int type;
691 
692 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
693 		switch (dav->dav_dat->dat_attr) {
694 		case DW_AT_encoding:
695 			enc = dav2val(dav, psz);
696 			break;
697 		case DW_AT_byte_size:
698 			bits = 8 * dav2val(dav, psz);
699 			break;
700 		default:
701 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
702 			break;
703 		}
704 	}
705 
706 	switch (enc) {
707 	case DW_ATE_unsigned:
708 	case DW_ATE_address:
709 		encoding = 0;
710 		type = CTF_K_INTEGER;
711 		break;
712 	case DW_ATE_unsigned_char:
713 		encoding = CTF_INT_CHAR;
714 		type = CTF_K_INTEGER;
715 		break;
716 	case DW_ATE_signed:
717 		encoding = CTF_INT_SIGNED;
718 		type = CTF_K_INTEGER;
719 		break;
720 	case DW_ATE_signed_char:
721 		encoding = CTF_INT_SIGNED | CTF_INT_CHAR;
722 		type = CTF_K_INTEGER;
723 		break;
724 	case DW_ATE_boolean:
725 		encoding = CTF_INT_SIGNED | CTF_INT_BOOL;
726 		type = CTF_K_INTEGER;
727 		break;
728 	case DW_ATE_float:
729 		if (bits < psz)
730 			encoding = CTF_FP_SINGLE;
731 		else if (bits == psz)
732 			encoding = CTF_FP_DOUBLE;
733 		else
734 			encoding = CTF_FP_LDOUBLE;
735 		type = CTF_K_FLOAT;
736 		break;
737 	case DW_ATE_complex_float:
738 		if (bits < psz)
739 			encoding = CTF_FP_CPLX;
740 		else if (bits == psz)
741 			encoding = CTF_FP_DCPLX;
742 		else
743 			encoding = CTF_FP_LDCPLX;
744 		type = CTF_K_FLOAT;
745 		break;
746 	case DW_ATE_imaginary_float:
747 		if (bits < psz)
748 			encoding = CTF_FP_IMAGRY;
749 		else if (bits == psz)
750 			encoding = CTF_FP_DIMAGRY;
751 		else
752 			encoding = CTF_FP_LDIMAGRY;
753 		type = CTF_K_FLOAT;
754 		break;
755 	default:
756 		DPRINTF("unknown encoding: %d\n", enc);
757 		return (NULL);
758 	}
759 
760 	it = it_new(++tidx, die->die_offset, enc2name(enc), bits,
761 	    encoding, 0, type, 0);
762 
763 	return it;
764 }
765 
766 struct itype *
767 parse_refers(struct dwdie *die, size_t psz, int type)
768 {
769 	struct itype *it;
770 	struct dwaval *dav;
771 	const char *name = NULL;
772 	size_t ref = 0, size = 0;
773 
774 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
775 		switch (dav->dav_dat->dat_attr) {
776 		case DW_AT_name:
777 			name = dav2str(dav);
778 			break;
779 		case DW_AT_type:
780 			ref = dav2val(dav, psz);
781 			break;
782 		case DW_AT_byte_size:
783 			size = dav2val(dav, psz);
784 			assert(size < UINT_MAX);
785 			break;
786 		default:
787 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
788 			break;
789 		}
790 	}
791 
792 	it = it_new(++tidx, die->die_offset, name, size, 0, ref, type,
793 	    ITF_UNRES);
794 
795 	if (it->it_ref == 0 && (it->it_size == sizeof(void *) ||
796 	    type == CTF_K_CONST || type == CTF_K_VOLATILE ||
797 	    type == CTF_K_POINTER)) {
798 		/* Work around GCC/clang not emiting a type for void */
799 		it->it_flags &= ~ITF_UNRES;
800 		it->it_ref = VOID_OFFSET;
801 		it->it_refp = void_it;
802 	}
803 
804 	return it;
805 }
806 
807 struct itype *
808 parse_array(struct dwdie *die, size_t psz)
809 {
810 	struct itype *it;
811 	struct dwaval *dav;
812 	const char *name = NULL;
813 	size_t ref = 0;
814 
815 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
816 		switch (dav->dav_dat->dat_attr) {
817 		case DW_AT_name:
818 			name = dav2str(dav);
819 			break;
820 		case DW_AT_type:
821 			ref = dav2val(dav, psz);
822 			break;
823 		default:
824 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
825 			break;
826 		}
827 	}
828 
829 	it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_ARRAY,
830 	    ITF_UNRES);
831 
832 	subparse_subrange(die, psz, it);
833 
834 	return it;
835 }
836 
837 struct itype *
838 parse_enum(struct dwdie *die, size_t psz)
839 {
840 	struct itype *it;
841 	struct dwaval *dav;
842 	const char *name = NULL;
843 	size_t size = 0;
844 
845 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
846 		switch (dav->dav_dat->dat_attr) {
847 		case DW_AT_byte_size:
848 			size = dav2val(dav, psz);
849 			assert(size < UINT_MAX);
850 			break;
851 		case DW_AT_name:
852 			name = dav2str(dav);
853 			break;
854 		default:
855 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
856 			break;
857 		}
858 	}
859 
860 	it = it_new(++tidx, die->die_offset, name, size, 0, 0, CTF_K_ENUM, 0);
861 
862 	subparse_enumerator(die, psz, it);
863 
864 	return it;
865 }
866 
867 void
868 subparse_subrange(struct dwdie *die, size_t psz, struct itype *it)
869 {
870 	struct dwaval *dav;
871 
872 	assert(it->it_type == CTF_K_ARRAY);
873 
874 	if (die->die_dab->dab_children == DW_CHILDREN_no)
875 		return;
876 
877 	/*
878 	 * This loop assumes that the children of a DIE are just
879 	 * after it on the list.
880 	 */
881 	while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
882 		uint64_t tag = die->die_dab->dab_tag;
883 		size_t nelems = 0;
884 
885 		if (tag != DW_TAG_subrange_type)
886 			break;
887 
888 		SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
889 			switch (dav->dav_dat->dat_attr) {
890 			case DW_AT_count:
891 				nelems = dav2val(dav, psz);
892 				break;
893 			case DW_AT_upper_bound:
894 				nelems = dav2val(dav, psz) + 1;
895 				break;
896 			default:
897 				DPRINTF("%s\n",
898 				    dw_at2name(dav->dav_dat->dat_attr));
899 				break;
900 			}
901 		}
902 
903 		assert(nelems < UINT_MAX);
904 		it->it_nelems = nelems;
905 	}
906 }
907 
908 void
909 subparse_enumerator(struct dwdie *die, size_t psz, struct itype *it)
910 {
911 	struct imember *im;
912 	struct dwaval *dav;
913 
914 	assert(it->it_type == CTF_K_ENUM);
915 
916 	if (die->die_dab->dab_children == DW_CHILDREN_no)
917 		return;
918 
919 	/*
920 	 * This loop assumes that the children of a DIE are just
921 	 * after it on the list.
922 	 */
923 	while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
924 		uint64_t tag = die->die_dab->dab_tag;
925 		size_t val = 0;
926 		const char *name = NULL;
927 
928 		if (tag != DW_TAG_enumerator)
929 			break;
930 
931 		SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
932 			switch (dav->dav_dat->dat_attr) {
933 			case DW_AT_name:
934 				name = dav2str(dav);
935 				break;
936 			case DW_AT_const_value:
937 				val = dav2val(dav, psz);
938 				break;
939 			default:
940 				DPRINTF("%s\n",
941 				    dw_at2name(dav->dav_dat->dat_attr));
942 				break;
943 			}
944 		}
945 
946 		if (name == NULL) {
947 			warnx("%s with anon member", it_name(it));
948 			continue;
949 		}
950 
951 		im = im_new(name, val, 0);
952 		assert(it->it_nelems < UINT_MAX);
953 		it->it_nelems++;
954 		TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
955 	}
956 }
957 
958 struct itype *
959 parse_struct(struct dwdie *die, size_t psz, int type, size_t off)
960 {
961 	struct itype *it = NULL;
962 	struct dwaval *dav;
963 	const char *name = NULL;
964 	size_t size = 0;
965 
966 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
967 		switch (dav->dav_dat->dat_attr) {
968 		case DW_AT_byte_size:
969 			size = dav2val(dav, psz);
970 			assert(size < UINT_MAX);
971 			break;
972 		case DW_AT_name:
973 			name = dav2str(dav);
974 			break;
975 		default:
976 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
977 			break;
978 		}
979 	}
980 
981 	it = it_new(++tidx, die->die_offset, name, size, 0, 0, type, 0);
982 
983 	subparse_member(die, psz, it, off);
984 
985 	return it;
986 }
987 
988 void
989 subparse_member(struct dwdie *die, size_t psz, struct itype *it, size_t offset)
990 {
991 	struct imember *im;
992 	struct dwaval *dav;
993 	const char *name;
994 	size_t off = 0, ref = 0, bits = 0;
995 	uint8_t lvl = die->die_lvl;
996 
997 	assert(it->it_type == CTF_K_STRUCT || it->it_type == CTF_K_UNION);
998 
999 	if (die->die_dab->dab_children == DW_CHILDREN_no)
1000 		return;
1001 
1002 	/*
1003 	 * This loop assumes that the children of a DIE are just
1004 	 * after it on the list.
1005 	 */
1006 	while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
1007 		int64_t tag = die->die_dab->dab_tag;
1008 
1009 		name = NULL;
1010 		if (die->die_lvl <= lvl)
1011 			break;
1012 
1013 		/* Skip members of members */
1014 		if (die->die_lvl > lvl + 1)
1015 			continue;
1016 		/*
1017 		 * Nested declaration.
1018 		 *
1019 		 * This matches the case where a ``struct'', ``union'',
1020 		 * ``enum'' or ``typedef'' is first declared "inside" a
1021 		 * union or struct declaration.
1022 		 */
1023 		if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type ||
1024 		    tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef)
1025 			continue;
1026 
1027 		it->it_flags |= ITF_UNRES_MEMB;
1028 
1029 		SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
1030 			switch (dav->dav_dat->dat_attr) {
1031 			case DW_AT_name:
1032 				name = dav2str(dav);
1033 				break;
1034 			case DW_AT_type:
1035 				ref = dav2val(dav, psz);
1036 				break;
1037 			case DW_AT_data_member_location:
1038 				off = 8 * dav2val(dav, psz);
1039 				break;
1040 			case DW_AT_bit_size:
1041 				bits = dav2val(dav, psz);
1042 				assert(bits < USHRT_MAX);
1043 				break;
1044 			default:
1045 				DPRINTF("%s\n",
1046 				    dw_at2name(dav->dav_dat->dat_attr));
1047 				break;
1048 			}
1049 		}
1050 
1051 		/*
1052 		 * When a structure is declared inside an union, we
1053 		 * have to generate a reference to make the resolver
1054 		 * happy.
1055 		 */
1056 		if ((ref == 0) && (tag == DW_TAG_structure_type))
1057 			ref = die->die_offset - offset;
1058 
1059 		im = im_new(name, ref, off);
1060 		assert(it->it_nelems < UINT_MAX);
1061 		it->it_nelems++;
1062 		TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
1063 	}
1064 }
1065 
1066 
1067 void
1068 subparse_arguments(struct dwdie *die, size_t psz, struct itype *it)
1069 {
1070 	struct imember *im;
1071 	struct dwaval *dav;
1072 	size_t ref = 0;
1073 
1074 	assert(it->it_type == CTF_K_FUNCTION);
1075 
1076 	if (die->die_dab->dab_children == DW_CHILDREN_no)
1077 		return;
1078 
1079 	/*
1080 	 * This loop assumes that the children of a DIE are after it
1081 	 * on the list.
1082 	 */
1083 	while ((die = SIMPLEQ_NEXT(die, die_next)) != NULL) {
1084 		uint64_t tag = die->die_dab->dab_tag;
1085 
1086 		if (tag == DW_TAG_unspecified_parameters) {
1087 			it->it_flags |= ITF_VARARGS;
1088 			continue;
1089 		}
1090 
1091 		/*
1092 		 * Nested declaration.
1093 		 *
1094 		 * This matches the case where a ``struct'', ``union'',
1095 		 * ``enum'' or ``typedef'' is first declared "inside" a
1096 		 * function declaration.
1097 		 */
1098 		if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type ||
1099 		    tag == DW_TAG_enumeration_type || tag == DW_TAG_typedef)
1100 			continue;
1101 
1102 		if (tag != DW_TAG_formal_parameter)
1103 			break;
1104 
1105 		it->it_flags |= ITF_UNRES_MEMB;
1106 
1107 		SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
1108 			switch (dav->dav_dat->dat_attr) {
1109 			case DW_AT_type:
1110 				ref = dav2val(dav, psz);
1111 				break;
1112 			default:
1113 				DPRINTF("%s\n",
1114 				    dw_at2name(dav->dav_dat->dat_attr));
1115 				break;
1116 			}
1117 		}
1118 
1119 		im = im_new(NULL, ref, 0);
1120 		assert(it->it_nelems < UINT_MAX);
1121 		it->it_nelems++;
1122 		TAILQ_INSERT_TAIL(&it->it_members, im, im_next);
1123 	}
1124 }
1125 
1126 struct itype *
1127 parse_function(struct dwdie *die, size_t psz)
1128 {
1129 	struct itype *it;
1130 	struct dwaval *dav;
1131 	const char *name = NULL;
1132 	size_t ref = 0;
1133 
1134 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
1135 		switch (dav->dav_dat->dat_attr) {
1136 		case DW_AT_name:
1137 			name = dav2str(dav);
1138 			break;
1139 		case DW_AT_type:
1140 			ref = dav2val(dav, psz);
1141 			break;
1142 		case DW_AT_abstract_origin:
1143 			/*
1144 			 * Skip second empty definition for inline
1145 			 * functions.
1146 			 */
1147 			return NULL;
1148 		default:
1149 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
1150 			break;
1151 		}
1152 	}
1153 
1154 	/*
1155 	 * Work around for clang 4.0 generating DW_TAG_subprogram without
1156 	 * any attribute.
1157 	 */
1158 	if (name == NULL)
1159 		return NULL;
1160 
1161 	it = it_new(++fidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION,
1162 	    ITF_UNRES|ITF_FUNC);
1163 
1164 	subparse_arguments(die, psz, it);
1165 
1166 	if (it->it_ref == 0) {
1167 		/* Work around GCC not emiting a type for void */
1168 		it->it_flags &= ~ITF_UNRES;
1169 		it->it_ref = VOID_OFFSET;
1170 		it->it_refp = void_it;
1171 	}
1172 
1173 	return it;
1174 }
1175 
1176 struct itype *
1177 parse_funcptr(struct dwdie *die, size_t psz)
1178 {
1179 	struct itype *it;
1180 	struct dwaval *dav;
1181 	const char *name = NULL;
1182 	size_t ref = 0;
1183 
1184 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
1185 		switch (dav->dav_dat->dat_attr) {
1186 		case DW_AT_name:
1187 			name = dav2str(dav);
1188 			break;
1189 		case DW_AT_type:
1190 			ref = dav2val(dav, psz);
1191 			break;
1192 		default:
1193 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
1194 			break;
1195 		}
1196 	}
1197 
1198 	it = it_new(++tidx, die->die_offset, name, 0, 0, ref, CTF_K_FUNCTION,
1199 	    ITF_UNRES);
1200 
1201 	subparse_arguments(die, psz, it);
1202 
1203 	if (it->it_ref == 0) {
1204 		/* Work around GCC not emiting a type for void */
1205 		it->it_flags &= ~ITF_UNRES;
1206 		it->it_ref = VOID_OFFSET;
1207 		it->it_refp = void_it;
1208 	}
1209 
1210 	return it;
1211 }
1212 
1213 struct itype *
1214 parse_variable(struct dwdie *die, size_t psz)
1215 {
1216 	struct itype *it = NULL;
1217 	struct dwaval *dav;
1218 	const char *name = NULL;
1219 	size_t ref = 0;
1220 	int declaration = 0;
1221 
1222 	SIMPLEQ_FOREACH(dav, &die->die_avals, dav_next) {
1223 		switch (dav->dav_dat->dat_attr) {
1224 		case DW_AT_declaration:
1225 			declaration = dav2val(dav, psz);
1226 			break;
1227 		case DW_AT_name:
1228 			name = dav2str(dav);
1229 			break;
1230 		case DW_AT_type:
1231 			ref = dav2val(dav, psz);
1232 			break;
1233 		default:
1234 			DPRINTF("%s\n", dw_at2name(dav->dav_dat->dat_attr));
1235 			break;
1236 		}
1237 	}
1238 
1239 
1240 	if (!declaration && name != NULL) {
1241 		it = it_new(++oidx, die->die_offset, name, 0, 0, ref, 0,
1242 		    ITF_UNRES|ITF_OBJ);
1243 	}
1244 
1245 	return it;
1246 }
1247 
1248 size_t
1249 dav2val(struct dwaval *dav, size_t psz)
1250 {
1251 	uint64_t val = (uint64_t)-1;
1252 
1253 	switch (dav->dav_dat->dat_form) {
1254 	case DW_FORM_addr:
1255 	case DW_FORM_ref_addr:
1256 		if (psz == sizeof(uint32_t))
1257 			val = dav->dav_u32;
1258 		else
1259 			val = dav->dav_u64;
1260 		break;
1261 	case DW_FORM_block1:
1262 	case DW_FORM_block2:
1263 	case DW_FORM_block4:
1264 	case DW_FORM_block:
1265 		dw_loc_parse(&dav->dav_buf, NULL, &val, NULL);
1266 		break;
1267 	case DW_FORM_flag:
1268 	case DW_FORM_data1:
1269 	case DW_FORM_ref1:
1270 		val = dav->dav_u8;
1271 		break;
1272 	case DW_FORM_data2:
1273 	case DW_FORM_ref2:
1274 		val = dav->dav_u16;
1275 		break;
1276 	case DW_FORM_data4:
1277 	case DW_FORM_ref4:
1278 		val = dav->dav_u32;
1279 		break;
1280 	case DW_FORM_sdata:
1281 	case DW_FORM_data8:
1282 	case DW_FORM_ref8:
1283 		val = dav->dav_u64;
1284 		break;
1285 	case DW_FORM_strp:
1286 		val = dav->dav_u32;
1287 		break;
1288 	case DW_FORM_flag_present:
1289 		val = 1;
1290 		break;
1291 	default:
1292 		break;
1293 	}
1294 
1295 	return val;
1296 }
1297 
1298 const char *
1299 dav2str(struct dwaval *dav)
1300 {
1301 	const char *str = NULL;
1302 	extern const char *dstrbuf;
1303 	extern size_t dstrlen;
1304 
1305 	switch (dav->dav_dat->dat_form) {
1306 	case DW_FORM_string:
1307 		str = dav->dav_str;
1308 		break;
1309 	case DW_FORM_strp:
1310 		if (dav->dav_u32 >= dstrlen)
1311 			str = NULL;
1312 		else
1313 			str = dstrbuf + dav->dav_u32;
1314 		break;
1315 	default:
1316 		break;
1317 	}
1318 
1319 	return str;
1320 }
1321 
1322 const char *
1323 enc2name(unsigned short enc)
1324 {
1325 	static const char *enc_name[] = { "address", "boolean", "complex float",
1326 	    "float", "signed", "char", "unsigned", "unsigned char",
1327 	    "imaginary float", "packed decimal", "numeric string", "edited",
1328 	    "signed fixed", "unsigned fixed", "decimal float" };
1329 
1330 	if (enc > 0 && enc <= nitems(enc_name))
1331 		return enc_name[enc - 1];
1332 
1333 	return "invalid";
1334 }
1335