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