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