1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26#pragma ident	"@(#)st_parse.c	1.14	06/08/22 SMI"
27
28/*
29 * This file is a sewer.
30 */
31
32#if !defined(__APPLE__)
33#include <limits.h>
34#include <stdarg.h>
35#include <stdio.h>
36#include <assert.h>
37#include <strings.h>
38#include <setjmp.h>
39#include <ctype.h>
40#include <uts/common/sys/ctf.h>
41
42#include "ctftools.h"
43#include "memory.h"
44#include "list.h"
45#else
46#include <limits.h>
47#include <stdarg.h>
48#include <stdio.h>
49#include <assert.h>
50#include <strings.h>
51#include <setjmp.h>
52#include <ctype.h>
53#include "darwin_shim.h"
54#include "ctf.h"
55
56#include "ctftools.h"
57#include "memory.h"
58#include "list.h"
59#endif /* __APPLE__ */
60
61#define	HASH(NUM)	((int)(NUM & (BUCKETS - 1)))
62#define	BUCKETS		128
63
64#define	TYPEPAIRMULT	10000
65#define	MAKETYPEID(file, num)	((file) * TYPEPAIRMULT + num)
66#define	TYPEFILE(tid)		((tid) / TYPEPAIRMULT)
67#define	TYPENUM(tid)		((tid) % TYPEPAIRMULT)
68
69#define	expected(a, b, c) _expected(a, b, c, __LINE__)
70
71static int faketypenumber = 100000000;
72
73static tdesc_t *hash_table[BUCKETS];
74static tdesc_t *name_table[BUCKETS];
75
76list_t *typedbitfldmems;
77
78static void reset(void);
79static jmp_buf	resetbuf;
80
81static char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp);
82static void enumdef(char *cp, tdesc_t **rtdp);
83static int compute_sum(const char *w);
84
85static char *number(char *cp, int *n);
86static char *name(char *cp, char **w);
87static char *id(char *cp, int *h);
88static char *whitesp(char *cp);
89static void addhash(tdesc_t *tdp, int num);
90static int tagadd(char *w, int h, tdesc_t *tdp);
91static char *tdefdecl(char *cp, int h, tdesc_t **rtdp);
92static char *intrinsic(char *cp, tdesc_t **rtdp);
93static char *arraydef(char *cp, tdesc_t **rtdp);
94
95extern int debug_level;
96int debug_parse = DEBUG_PARSE;
97
98/*PRINTFLIKE3*/
99static void
100parse_debug(int level, char *cp, char *fmt, ...)
101{
102	va_list ap;
103	char buf[1024];
104	char tmp[32];
105	int i;
106
107	if (level > debug_level || !debug_parse)
108		return;
109
110	if (cp != NULL) {
111		for (i = 0; i < 30; i++) {
112			if (cp[i] == '\0')
113				break;
114			if (!iscntrl(cp[i]))
115				tmp[i] = cp[i];
116		}
117		tmp[i] = '\0';
118		(void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp);
119	} else {
120		strcpy(buf, fmt);
121		strcat(buf, "\n");
122	}
123
124	va_start(ap, fmt);
125	vadebug(level, buf, ap);
126	va_end(ap);
127}
128
129/* Report unexpected syntax in stabs. */
130static void
131_expected(
132	char *who,	/* what function, or part thereof, is reporting */
133	char *what,	/* what was expected */
134	char *where,	/* where we were in the line of input */
135	int line)
136{
137	fprintf(stderr, "%s, expecting \"%s\" at \"%s\"\n", who, what, where);
138	fprintf(stderr, "code line: %d, file %s\n", line,
139	    (curhdr ? curhdr : "NO FILE"));
140	reset();
141}
142
143/*ARGSUSED*/
144void
145parse_init(tdata_t *td)
146{
147	int i;
148
149	for (i = 0; i < BUCKETS; i++) {
150		hash_table[i] = NULL;
151		name_table[i] = NULL;
152	}
153
154	if (typedbitfldmems != NULL) {
155		list_free(typedbitfldmems, NULL, NULL);
156		typedbitfldmems = NULL;
157	}
158}
159
160void
161parse_finish(tdata_t *td)
162{
163	td->td_nextid = ++faketypenumber;
164}
165
166static tdesc_t *
167unres_new(int tid)
168{
169	tdesc_t *tdp;
170
171	tdp = xcalloc(sizeof (*tdp));
172	tdp->t_type = TYPEDEF_UNRES;
173	tdp->t_id = tid;
174
175	return (tdp);
176}
177
178char *
179read_tid(char *cp, tdesc_t **tdpp)
180{
181	tdesc_t *tdp;
182	int tid;
183
184	cp = id(cp, &tid);
185
186	assert(tid != 0);
187
188	if (*cp == '=') {
189		if (!(cp = tdefdecl(cp + 1, tid, &tdp)))
190			return (NULL);
191		if (tdp->t_id && tdp->t_id != tid) {
192			tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
193
194			ntdp->t_type = TYPEDEF;
195			ntdp->t_tdesc = tdp;
196			tdp = ntdp;
197		}
198		addhash(tdp, tid);
199	} else if ((tdp = lookup(tid)) == NULL)
200		tdp = unres_new(tid);
201
202	*tdpp = tdp;
203	return (cp);
204}
205
206static iitype_t
207parse_fun(char *cp, iidesc_t *ii)
208{
209	iitype_t iitype;
210	tdesc_t *tdp;
211	tdesc_t **args = NULL;
212	int nargs = 0;
213	int va = 0;
214
215	/*
216	 * name:P		prototype
217	 * name:F		global function
218	 * name:f		static function
219	 */
220	switch (*cp++) {
221	case 'P':
222		iitype = II_NOT; /* not interesting */
223		break;
224
225	case 'F':
226		iitype = II_GFUN;
227		break;
228
229	case 'f':
230		iitype = II_SFUN;
231		break;
232
233	default:
234		expected("parse_nfun", "[PfF]", cp - 1);
235	}
236
237	if (!(cp = read_tid(cp, &tdp)))
238		return (-1);
239
240	if (*cp)
241		args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF);
242
243	while (*cp && *++cp) {
244		if (*cp == '0') {
245			va = 1;
246			continue;
247		}
248
249		nargs++;
250		if (nargs > FUNCARG_DEF)
251			args = xrealloc(args, sizeof (tdesc_t *) * nargs);
252		if (!(cp = read_tid(cp, &args[nargs - 1])))
253			return (-1);
254	}
255
256	ii->ii_type = iitype;
257	ii->ii_dtype = tdp;
258	ii->ii_nargs = nargs;
259	ii->ii_args = args;
260	ii->ii_vargs = va;
261
262	return (iitype);
263}
264
265static iitype_t
266parse_sym(char *cp, iidesc_t *ii)
267{
268	tdesc_t *tdp;
269	iitype_t iitype;
270
271	/*
272	 * name:G		global variable
273	 * name:S		static variable
274	 */
275	switch (*cp++) {
276	case 'G':
277		iitype = II_GVAR;
278		break;
279	case 'S':
280		iitype = II_SVAR;
281		break;
282	case 'p':
283		iitype = II_PSYM;
284		break;
285	case '(':
286		cp--;
287		/*FALLTHROUGH*/
288	case 'r':
289	case 'V':
290		iitype = II_NOT; /* not interesting */
291		break;
292	default:
293		expected("parse_sym", "[GprSV(]", cp - 1);
294	}
295
296	if (!(cp = read_tid(cp, &tdp)))
297		return (-1);
298
299	ii->ii_type = iitype;
300	ii->ii_dtype = tdp;
301
302	return (iitype);
303}
304
305static iitype_t
306parse_type(char *cp, iidesc_t *ii)
307{
308	tdesc_t *tdp, *ntdp;
309	int tid;
310
311	if (*cp++ != 't')
312		expected("parse_type", "t (type)", cp - 1);
313
314	cp = id(cp, &tid);
315	if ((tdp = lookup(tid)) == NULL) {
316		if (*cp++ != '=')
317			expected("parse_type", "= (definition)", cp - 1);
318
319		(void) tdefdecl(cp, tid, &tdp);
320
321		if (tdp->t_id == tid) {
322			assert(tdp->t_type != TYPEDEF);
323			assert(!lookup(tdp->t_id));
324
325			if (!streq(tdp->t_name, ii->ii_name)) {
326				ntdp = xcalloc(sizeof (*ntdp));
327				ntdp->t_name = xstrdup(ii->ii_name);
328				ntdp->t_type = TYPEDEF;
329				ntdp->t_tdesc = tdp;
330				tdp->t_id = faketypenumber++;
331				tdp = ntdp;
332			}
333		} else if (tdp->t_id == 0) {
334			assert(tdp->t_type == FORWARD ||
335			    tdp->t_type == INTRINSIC);
336
337			if (tdp->t_name && !streq(tdp->t_name, ii->ii_name)) {
338				ntdp = xcalloc(sizeof (*ntdp));
339				ntdp->t_name = xstrdup(ii->ii_name);
340				ntdp->t_type = TYPEDEF;
341				ntdp->t_tdesc = tdp;
342				tdp->t_id = faketypenumber++;
343				tdp = ntdp;
344			}
345		} else if (tdp->t_id != tid) {
346			ntdp = xcalloc(sizeof (*ntdp));
347			ntdp->t_name = xstrdup(ii->ii_name);
348			ntdp->t_type = TYPEDEF;
349			ntdp->t_tdesc = tdp;
350			tdp = ntdp;
351		}
352
353		if (tagadd(ii->ii_name, tid, tdp) < 0)
354			return (-1);
355	}
356
357	ii->ii_type = II_TYPE;
358	ii->ii_dtype = tdp;
359	return (II_TYPE);
360}
361
362static iitype_t
363parse_sou(char *cp, iidesc_t *idp)
364{
365	tdesc_t *rtdp;
366	int tid;
367
368	if (*cp++ != 'T')
369		expected("parse_sou", "T (sou)", cp - 1);
370
371	cp = id(cp, &tid);
372	if (*cp++ != '=')
373		expected("parse_sou", "= (definition)", cp - 1);
374
375	parse_debug(1, NULL, "parse_sou: declaring '%s'", idp->ii_name ?
376	    idp->ii_name : "(anon)");
377	if ((rtdp = lookup(tid)) != NULL) {
378		if (idp->ii_name != NULL) {
379			if (rtdp->t_name != NULL &&
380			    strcmp(rtdp->t_name, idp->ii_name) != 0) {
381				tdesc_t *tdp;
382
383				tdp = xcalloc(sizeof (*tdp));
384				tdp->t_name = xstrdup(idp->ii_name);
385				tdp->t_type = TYPEDEF;
386				tdp->t_tdesc = rtdp;
387				addhash(tdp, tid); /* for *(x,y) types */
388				parse_debug(3, NULL, "    %s defined as %s(%d)",
389				    idp->ii_name, tdesc_name(rtdp), tid);
390			} else if (rtdp->t_name == NULL) {
391				rtdp->t_name = xstrdup(idp->ii_name);
392				addhash(rtdp, tid);
393			}
394		}
395	} else {
396		rtdp = xcalloc(sizeof (*rtdp));
397		rtdp->t_name = idp->ii_name ? xstrdup(idp->ii_name) : NULL;
398		addhash(rtdp, tid);
399	}
400
401	switch (*cp++) {
402	case 's':
403		(void) soudef(cp, STRUCT, &rtdp);
404		break;
405	case 'u':
406		(void) soudef(cp, UNION, &rtdp);
407		break;
408	case 'e':
409		enumdef(cp, &rtdp);
410		break;
411	default:
412		expected("parse_sou", "<tag type s/u/e>", cp - 1);
413		break;
414	}
415
416	idp->ii_type = II_SOU;
417	idp->ii_dtype = rtdp;
418	return (II_SOU);
419}
420
421int
422parse_stab(stab_t *stab, char *cp, iidesc_t **iidescp)
423{
424	iidesc_t *ii = NULL;
425	iitype_t (*parse)(char *, iidesc_t *);
426	int rc;
427
428	/*
429	 * set up for reset()
430	 */
431	if (setjmp(resetbuf))
432		return (-1);
433
434	cp = whitesp(cp);
435	ii = iidesc_new(NULL);
436	cp = name(cp, &ii->ii_name);
437
438	switch (stab->n_type) {
439	case N_FUN:
440		parse = parse_fun;
441		break;
442
443	case N_LSYM:
444		if (*cp == 't')
445			parse = parse_type;
446		else if (*cp == 'T')
447			parse = parse_sou;
448		else
449			parse = parse_sym;
450		break;
451
452	case N_GSYM:
453	case N_LCSYM:
454	case N_PSYM:
455	case N_ROSYM:
456	case N_RSYM:
457	case N_STSYM:
458		parse = parse_sym;
459		break;
460	default:
461		parse_debug(1, cp, "Unknown stab type %#x", stab->n_type);
462		bzero(&resetbuf, sizeof (resetbuf));
463		return (-1);
464	}
465
466	rc = parse(cp, ii);
467	bzero(&resetbuf, sizeof (resetbuf));
468
469	if (rc < 0 || ii->ii_type == II_NOT) {
470		iidesc_free(ii, NULL);
471		return (rc);
472	}
473
474	*iidescp = ii;
475
476	return (1);
477}
478
479/*
480 * Check if we have this node in the hash table already
481 */
482tdesc_t *
483lookup(int h)
484{
485	int bucket = HASH(h);
486	tdesc_t *tdp = hash_table[bucket];
487
488	while (tdp != NULL) {
489		if (tdp->t_id == h)
490			return (tdp);
491		tdp = tdp->t_hash;
492	}
493	return (NULL);
494}
495
496static char *
497whitesp(char *cp)
498{
499	char c;
500
501	for (c = *cp++; isspace(c); c = *cp++);
502	--cp;
503	return (cp);
504}
505
506static char *
507name(char *cp, char **w)
508{
509	char *new, *orig, c;
510	int len;
511
512	orig = cp;
513	c = *cp++;
514	if (c == ':')
515		*w = NULL;
516	else if (isalpha(c) || strchr("_.$", c)) {
517		for (c = *cp++; isalnum(c) || strchr(" _.$", c); c = *cp++)
518			;
519		if (c != ':')
520			reset();
521		len = cp - orig;
522		new = xmalloc(len);
523		while (orig < cp - 1)
524			*new++ = *orig++;
525		*new = '\0';
526		*w = new - (len - 1);
527	} else
528		reset();
529
530	return (cp);
531}
532
533static char *
534number(char *cp, int *n)
535{
536	char *next;
537
538	*n = (int)strtol(cp, &next, 10);
539	if (next == cp)
540		expected("number", "<number>", cp);
541	return (next);
542}
543
544static char *
545id(char *cp, int *h)
546{
547	int n1, n2;
548
549	if (*cp == '(') {	/* SunPro style */
550		cp++;
551		cp = number(cp, &n1);
552		if (*cp++ != ',')
553			expected("id", ",", cp - 1);
554		cp = number(cp, &n2);
555		if (*cp++ != ')')
556			expected("id", ")", cp - 1);
557		*h = MAKETYPEID(n1, n2);
558	} else if (isdigit(*cp)) { /* gcc style */
559		cp = number(cp, &n1);
560		*h = n1;
561	} else {
562		expected("id", "(/0-9", cp);
563	}
564	return (cp);
565}
566
567static int
568tagadd(char *w, int h, tdesc_t *tdp)
569{
570	tdesc_t *otdp;
571
572	tdp->t_name = w;
573	if (!(otdp = lookup(h)))
574		addhash(tdp, h);
575	else if (otdp != tdp) {
576		warning("duplicate entry\n");
577		warning("  old: %s %d (%d,%d)\n", tdesc_name(otdp),
578		    otdp->t_type, TYPEFILE(otdp->t_id), TYPENUM(otdp->t_id));
579		warning("  new: %s %d (%d,%d)\n", tdesc_name(tdp),
580		    tdp->t_type, TYPEFILE(tdp->t_id), TYPENUM(tdp->t_id));
581		return (-1);
582	}
583
584	return (0);
585}
586
587static char *
588tdefdecl(char *cp, int h, tdesc_t **rtdp)
589{
590	tdesc_t *ntdp;
591	char *w;
592	int c, h2;
593	char type;
594
595	parse_debug(3, cp, "tdefdecl h=%d", h);
596
597	/* Type codes */
598	switch (type = *cp) {
599	case 'b': /* integer */
600	case 'R': /* fp */
601		cp = intrinsic(cp, rtdp);
602		break;
603	case '(': /* equiv to another type */
604		cp = id(cp, &h2);
605		ntdp = lookup(h2);
606
607		if (ntdp != NULL && *cp == '=') {
608			if (ntdp->t_type == FORWARD && *(cp + 1) == 'x') {
609				/*
610				 * The 6.2 compiler, and possibly others, will
611				 * sometimes emit the same stab for a forward
612				 * declaration twice.  That is, "(1,2)=xsfoo:"
613				 * will sometimes show up in two different
614				 * places.  This is, of course, quite fun.  We
615				 * want CTF to work in spite of the compiler,
616				 * so we'll let this one through.
617				 */
618				char *c2 = cp + 2;
619				char *nm;
620
621				if (!strchr("sue", *c2++)) {
622					expected("tdefdecl/x-redefine", "[sue]",
623					    c2 - 1);
624				}
625
626				c2 = name(c2, &nm);
627				if (strcmp(nm, ntdp->t_name) != 0) {
628					terminate("Stabs error: Attempt to "
629					    "redefine type (%d,%d) as "
630					    "something else: %s\n",
631					    TYPEFILE(h2), TYPENUM(h2),
632					    c2 - 1);
633				}
634				free(nm);
635
636				h2 = faketypenumber++;
637				ntdp = NULL;
638			} else {
639				terminate("Stabs error: Attempting to "
640				    "redefine type (%d,%d)\n", TYPEFILE(h2),
641				    TYPENUM(h2));
642			}
643		}
644
645		if (ntdp == NULL) {  /* if that type isn't defined yet */
646			if (*cp != '=') {
647				/* record it as unresolved */
648				parse_debug(3, NULL, "tdefdecl unres type %d",
649				    h2);
650				*rtdp = calloc(sizeof (**rtdp), 1);
651				(*rtdp)->t_type = TYPEDEF_UNRES;
652				(*rtdp)->t_id = h2;
653				break;
654			} else
655				cp++;
656
657			/* define a new type */
658			cp = tdefdecl(cp, h2, rtdp);
659			if ((*rtdp)->t_id && (*rtdp)->t_id != h2) {
660				ntdp = calloc(sizeof (*ntdp), 1);
661				ntdp->t_type = TYPEDEF;
662				ntdp->t_tdesc = *rtdp;
663				*rtdp = ntdp;
664			}
665
666			addhash(*rtdp, h2);
667
668		} else { /* that type is already defined */
669			if (ntdp->t_type != TYPEDEF || ntdp->t_name != NULL) {
670				*rtdp = ntdp;
671			} else {
672				parse_debug(3, NULL,
673				    "No duplicate typedef anon for ref");
674				*rtdp = ntdp;
675			}
676		}
677		break;
678	case '*':
679		ntdp = NULL;
680		cp = tdefdecl(cp + 1, h, &ntdp);
681		if (ntdp == NULL)
682			expected("tdefdecl/*", "id", cp);
683
684		if (!ntdp->t_id)
685			ntdp->t_id = faketypenumber++;
686
687		*rtdp = xcalloc(sizeof (**rtdp));
688		(*rtdp)->t_type = POINTER;
689		(*rtdp)->t_size = 0;
690		(*rtdp)->t_id = h;
691		(*rtdp)->t_tdesc = ntdp;
692		break;
693	case 'f':
694		cp = tdefdecl(cp + 1, h, &ntdp);
695		*rtdp = xcalloc(sizeof (**rtdp));
696		(*rtdp)->t_type = FUNCTION;
697		(*rtdp)->t_size = 0;
698		(*rtdp)->t_id = h;
699		(*rtdp)->t_fndef = xcalloc(sizeof (fndef_t));
700		/*
701		 * The 6.1 compiler will sometimes generate incorrect stabs for
702		 * function pointers (it'll get the return type wrong).  This
703		 * causes merges to fail.  We therefore treat function pointers
704		 * as if they all point to functions that return int.  When
705		 * 4432549 is fixed, the lookupname() call below should be
706		 * replaced with `ntdp'.
707		 */
708		(*rtdp)->t_fndef->fn_ret = lookupname("int");
709		break;
710	case 'a':
711	case 'z':
712		cp++;
713		if (*cp++ != 'r')
714			expected("tdefdecl/[az]", "r", cp - 1);
715		*rtdp = xcalloc(sizeof (**rtdp));
716		(*rtdp)->t_type = ARRAY;
717		(*rtdp)->t_id = h;
718		cp = arraydef(cp, rtdp);
719		break;
720	case 'x':
721		c = *++cp;
722		if (c != 's' && c != 'u' && c != 'e')
723			expected("tdefdecl/x", "[sue]", cp - 1);
724		cp = name(cp + 1, &w);
725
726		ntdp = xcalloc(sizeof (*ntdp));
727		ntdp->t_type = FORWARD;
728		ntdp->t_name = w;
729		/*
730		 * We explicitly don't set t_id here - the caller will do it.
731		 * The caller may want to use a real type ID, or they may
732		 * choose to make one up.
733		 */
734
735		*rtdp = ntdp;
736		break;
737
738	case 'B': /* volatile */
739		cp = tdefdecl(cp + 1, h, &ntdp);
740
741		if (!ntdp->t_id)
742			ntdp->t_id = faketypenumber++;
743
744		*rtdp = xcalloc(sizeof (**rtdp));
745		(*rtdp)->t_type = VOLATILE;
746		(*rtdp)->t_size = 0;
747		(*rtdp)->t_tdesc = ntdp;
748		(*rtdp)->t_id = h;
749		break;
750
751	case 'k': /* const */
752		cp = tdefdecl(cp + 1, h, &ntdp);
753
754		if (!ntdp->t_id)
755			ntdp->t_id = faketypenumber++;
756
757		*rtdp = xcalloc(sizeof (**rtdp));
758		(*rtdp)->t_type = CONST;
759		(*rtdp)->t_size = 0;
760		(*rtdp)->t_tdesc = ntdp;
761		(*rtdp)->t_id = h;
762		break;
763
764	case 'K': /* restricted */
765		cp = tdefdecl(cp + 1, h, &ntdp);
766
767		if (!ntdp->t_id)
768			ntdp->t_id = faketypenumber++;
769
770		*rtdp = xcalloc(sizeof (**rtdp));
771		(*rtdp)->t_type = RESTRICT;
772		(*rtdp)->t_size = 0;
773		(*rtdp)->t_tdesc = ntdp;
774		(*rtdp)->t_id = h;
775		break;
776
777	case 'u':
778	case 's':
779		cp++;
780
781		*rtdp = xcalloc(sizeof (**rtdp));
782		(*rtdp)->t_name = NULL;
783		cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
784		break;
785	default:
786		expected("tdefdecl", "<type code>", cp);
787	}
788	return (cp);
789}
790
791static char *
792intrinsic(char *cp, tdesc_t **rtdp)
793{
794	intr_t *intr = xcalloc(sizeof (intr_t));
795	tdesc_t *tdp;
796	int width, fmt, i;
797
798	switch (*cp++) {
799	case 'b':
800		intr->intr_type = INTR_INT;
801		if (*cp == 's')
802			intr->intr_signed = 1;
803		else if (*cp != 'u')
804			expected("intrinsic/b", "[su]", cp);
805		cp++;
806
807		if (strchr("cbv", *cp))
808			intr->intr_iformat = *cp++;
809
810		cp = number(cp, &width);
811		if (*cp++ != ';')
812			expected("intrinsic/b", "; (post-width)", cp - 1);
813
814		cp = number(cp, &intr->intr_offset);
815		if (*cp++ != ';')
816			expected("intrinsic/b", "; (post-offset)", cp - 1);
817
818		cp = number(cp, &intr->intr_nbits);
819		break;
820
821	case 'R':
822		intr->intr_type = INTR_REAL;
823		for (fmt = 0, i = 0; isdigit(*(cp + i)); i++)
824			fmt = fmt * 10 + (*(cp + i) - '0');
825
826		if (fmt < 1 || fmt > CTF_FP_MAX)
827			expected("intrinsic/R", "number <= CTF_FP_MAX", cp);
828
829		intr->intr_fformat = fmt;
830		cp += i;
831
832		if (*cp++ != ';')
833			expected("intrinsic/R", ";", cp - 1);
834		cp = number(cp, &width);
835
836		intr->intr_nbits = width * 8;
837		break;
838	}
839
840	tdp = xcalloc(sizeof (*tdp));
841	tdp->t_type = INTRINSIC;
842	tdp->t_size = width;
843	tdp->t_name = NULL;
844	tdp->t_intr = intr;
845	parse_debug(3, NULL, "intrinsic: size=%d", width);
846	*rtdp = tdp;
847
848	return (cp);
849}
850
851static tdesc_t *
852bitintrinsic(tdesc_t *template, int nbits)
853{
854	tdesc_t *newtdp = xcalloc(sizeof (tdesc_t));
855
856	newtdp->t_name = xstrdup(template->t_name);
857	newtdp->t_id = faketypenumber++;
858	newtdp->t_type = INTRINSIC;
859	newtdp->t_size = template->t_size;
860	newtdp->t_intr = xmalloc(sizeof (intr_t));
861	bcopy(template->t_intr, newtdp->t_intr, sizeof (intr_t));
862	newtdp->t_intr->intr_nbits = nbits;
863
864	return (newtdp);
865}
866
867static char *
868offsize(char *cp, mlist_t *mlp)
869{
870	int offset, size;
871
872	if (*cp == ',')
873		cp++;
874	cp = number(cp, &offset);
875	if (*cp++ != ',')
876		expected("offsize/2", ",", cp - 1);
877	cp = number(cp, &size);
878	if (*cp++ != ';')
879		expected("offsize/3", ";", cp - 1);
880	mlp->ml_offset = offset;
881	mlp->ml_size = size;
882	return (cp);
883}
884
885static tdesc_t *
886find_intrinsic(tdesc_t *tdp)
887{
888	for (;;) {
889		switch (tdp->t_type) {
890		case TYPEDEF:
891		case VOLATILE:
892		case CONST:
893		case RESTRICT:
894			tdp = tdp->t_tdesc;
895			break;
896
897		default:
898			return (tdp);
899		}
900	}
901}
902
903static char *
904soudef(char *cp, stabtype_t type, tdesc_t **rtdp)
905{
906	mlist_t *mlp, **prev;
907	char *w;
908	int h;
909	int size;
910	tdesc_t *tdp, *itdp;
911
912	cp = number(cp, &size);
913	(*rtdp)->t_size = size;
914	(*rtdp)->t_type = type; /* s or u */
915
916	/*
917	 * An '@' here indicates a bitmask follows.   This is so the
918	 * compiler can pass information to debuggers about how structures
919	 * are passed in the v9 world.  We don't need this information
920	 * so we skip over it.
921	 */
922	if (cp[0] == '@') {
923		cp += 3;
924	}
925
926	parse_debug(3, cp, "soudef: %s size=%d", tdesc_name(*rtdp),
927	    (*rtdp)->t_size);
928
929	prev = &((*rtdp)->t_members);
930	/* now fill up the fields */
931	while ((*cp != '\0') && (*cp != ';')) { /* signifies end of fields */
932		mlp = xcalloc(sizeof (*mlp));
933		*prev = mlp;
934		cp = name(cp, &w);
935		mlp->ml_name = w;
936		cp = id(cp, &h);
937		/*
938		 * find the tdesc struct in the hash table for this type
939		 * and stick a ptr in here
940		 */
941		tdp = lookup(h);
942		if (tdp == NULL) { /* not in hash list */
943			parse_debug(3, NULL, "      defines %s (%d)", w, h);
944			if (*cp++ != '=') {
945				tdp = unres_new(h);
946				parse_debug(3, NULL,
947				    "      refers to %s (unresolved %d)",
948				    (w ? w : "anon"), h);
949			} else {
950				cp = tdefdecl(cp, h, &tdp);
951
952				if (tdp->t_id && tdp->t_id != h) {
953					tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
954
955					ntdp->t_type = TYPEDEF;
956					ntdp->t_tdesc = tdp;
957					tdp = ntdp;
958				}
959
960				addhash(tdp, h);
961				parse_debug(4, cp,
962				    "     soudef now looking at    ");
963				cp++;
964			}
965		} else {
966			parse_debug(3, NULL, "      refers to %s (%d, %s)",
967			    w ? w : "anon", h, tdesc_name(tdp));
968		}
969
970		cp = offsize(cp, mlp);
971
972		itdp = find_intrinsic(tdp);
973		if (itdp->t_type == INTRINSIC) {
974			if (mlp->ml_size != itdp->t_intr->intr_nbits) {
975				parse_debug(4, cp, "making %d bit intrinsic "
976				    "from %s", mlp->ml_size, tdesc_name(itdp));
977				mlp->ml_type = bitintrinsic(itdp, mlp->ml_size);
978			} else
979				mlp->ml_type = tdp;
980		} else if (itdp->t_type == TYPEDEF_UNRES) {
981			list_add(&typedbitfldmems, mlp);
982			mlp->ml_type = tdp;
983		} else {
984			mlp->ml_type = tdp;
985		}
986
987		/* cp is now pointing to next field */
988		prev = &mlp->ml_next;
989	}
990	return (cp);
991}
992
993static char *
994arraydef(char *cp, tdesc_t **rtdp)
995{
996	int start, end, h;
997
998	cp = id(cp, &h);
999	if (*cp++ != ';')
1000		expected("arraydef/1", ";", cp - 1);
1001
1002	(*rtdp)->t_ardef = xcalloc(sizeof (ardef_t));
1003	(*rtdp)->t_ardef->ad_idxtype = lookup(h);
1004
1005	cp = number(cp, &start); /* lower */
1006	if (*cp++ != ';')
1007		expected("arraydef/2", ";", cp - 1);
1008
1009	if (*cp == 'S') {
1010		/* variable length array - treat as null dimensioned */
1011		cp++;
1012		if (*cp++ != '-')
1013			expected("arraydef/fpoff-sep", "-", cp - 1);
1014		cp = number(cp, &end);
1015		end = start;
1016	} else {
1017		/* normal fixed-dimension array */
1018		cp = number(cp, &end);  /* upper */
1019	}
1020
1021	if (*cp++ != ';')
1022		expected("arraydef/3", ";", cp - 1);
1023	(*rtdp)->t_ardef->ad_nelems = end - start + 1;
1024	cp = tdefdecl(cp, h, &((*rtdp)->t_ardef->ad_contents));
1025
1026	parse_debug(3, cp, "defined array idx type %d %d-%d next ",
1027	    h, start, end);
1028
1029	return (cp);
1030}
1031
1032static void
1033enumdef(char *cp, tdesc_t **rtdp)
1034{
1035	elist_t *elp, **prev;
1036	char *w;
1037
1038	(*rtdp)->t_type = ENUM;
1039	(*rtdp)->t_emem = NULL;
1040
1041	prev = &((*rtdp)->t_emem);
1042	while (*cp != ';') {
1043		elp = xcalloc(sizeof (*elp));
1044		elp->el_next = NULL;
1045		*prev = elp;
1046		cp = name(cp, &w);
1047		elp->el_name = w;
1048		cp = number(cp, &elp->el_number);
1049		parse_debug(3, NULL, "enum %s: %s=%d", tdesc_name(*rtdp),
1050		    elp->el_name, elp->el_number);
1051		prev = &elp->el_next;
1052		if (*cp++ != ',')
1053			expected("enumdef", ",", cp - 1);
1054	}
1055}
1056
1057tdesc_t *
1058lookup_name(tdesc_t **hash, const char *name)
1059{
1060	int bucket = compute_sum(name);
1061	tdesc_t *tdp, *ttdp = NULL;
1062
1063	for (tdp = hash[bucket]; tdp != NULL; tdp = tdp->t_next) {
1064		if (tdp->t_name != NULL && strcmp(tdp->t_name, name) == 0) {
1065			if (tdp->t_type == STRUCT || tdp->t_type == UNION ||
1066			    tdp->t_type == ENUM || tdp->t_type == INTRINSIC)
1067				return (tdp);
1068			if (tdp->t_type == TYPEDEF)
1069				ttdp = tdp;
1070		}
1071	}
1072	return (ttdp);
1073}
1074
1075tdesc_t *
1076lookupname(const char *name)
1077{
1078	return (lookup_name(name_table, name));
1079}
1080
1081/*
1082 * Add a node to the hash queues.
1083 */
1084static void
1085addhash(tdesc_t *tdp, int num)
1086{
1087	int hash = HASH(num);
1088	tdesc_t *ttdp;
1089	char added_num = 0, added_name = 0;
1090
1091	/*
1092	 * If it already exists in the hash table don't add it again
1093	 * (but still check to see if the name should be hashed).
1094	 */
1095	ttdp = lookup(num);
1096
1097	if (ttdp == NULL) {
1098		tdp->t_id = num;
1099		tdp->t_hash = hash_table[hash];
1100		hash_table[hash] = tdp;
1101		added_num = 1;
1102	}
1103
1104	if (tdp->t_name != NULL) {
1105		ttdp = lookupname(tdp->t_name);
1106		if (ttdp == NULL) {
1107			hash = compute_sum(tdp->t_name);
1108			tdp->t_next = name_table[hash];
1109			name_table[hash] = tdp;
1110			added_name = 1;
1111		}
1112	}
1113	if (!added_num && !added_name) {
1114		terminate("stabs: broken hash\n");
1115	}
1116}
1117
1118static int
1119compute_sum(const char *w)
1120{
1121	char c;
1122	int sum;
1123
1124	for (sum = 0; (c = *w) != '\0'; sum += c, w++)
1125		;
1126	return (HASH(sum));
1127}
1128
1129static void
1130reset(void)
1131{
1132	longjmp(resetbuf, 1);
1133}
1134
1135void
1136check_hash(void)
1137{
1138	tdesc_t *tdp;
1139	int i;
1140
1141	printf("checking hash\n");
1142	for (i = 0; i < BUCKETS; i++) {
1143		if (hash_table[i]) {
1144			for (tdp = hash_table[i]->t_hash;
1145			    tdp && tdp != hash_table[i];
1146			    tdp = tdp->t_hash)
1147				continue;
1148			if (tdp) {
1149				terminate("cycle in hash bucket %d\n", i);
1150				return;
1151			}
1152		}
1153
1154		if (name_table[i]) {
1155			for (tdp = name_table[i]->t_next;
1156			    tdp && tdp != name_table[i];
1157			    tdp = tdp->t_next)
1158				continue;
1159			if (tdp) {
1160				terminate("cycle in name bucket %d\n", i);
1161				return;
1162			}
1163		}
1164	}
1165	printf("done\n");
1166}
1167
1168/*ARGSUSED1*/
1169static int
1170resolve_typed_bitfields_cb(mlist_t *ml, void *private)
1171{
1172	tdesc_t *tdp = ml->ml_type;
1173
1174	debug(3, "Resolving typed bitfields (member %s)\n",
1175	    (ml->ml_name ? ml->ml_name : "(anon)"));
1176
1177	while (tdp) {
1178		switch (tdp->t_type) {
1179		case INTRINSIC:
1180			if (ml->ml_size != tdp->t_intr->intr_nbits) {
1181				debug(3, "making %d bit intrinsic from %s",
1182				    ml->ml_size, tdesc_name(tdp));
1183				ml->ml_type = bitintrinsic(tdp, ml->ml_size);
1184			} else {
1185				debug(3, "using existing %d bit %s intrinsic",
1186				    ml->ml_size, tdesc_name(tdp));
1187				ml->ml_type = tdp;
1188			}
1189			return (1);
1190
1191		case POINTER:
1192		case TYPEDEF:
1193		case VOLATILE:
1194		case CONST:
1195		case RESTRICT:
1196			tdp = tdp->t_tdesc;
1197			break;
1198
1199		default:
1200			return (1);
1201		}
1202	}
1203
1204	terminate("type chain for bitfield member %s has a NULL", ml->ml_name);
1205	/*NOTREACHED*/
1206	return (0);
1207}
1208
1209void
1210resolve_typed_bitfields(void)
1211{
1212	(void) list_iter(typedbitfldmems,
1213	    (int (*)())resolve_typed_bitfields_cb, NULL);
1214}
1215