st_parse.c revision 178481
1178481Sjb/*
2178481Sjb * CDDL HEADER START
3178481Sjb *
4178481Sjb * The contents of this file are subject to the terms of the
5178481Sjb * Common Development and Distribution License (the "License").
6178481Sjb * You may not use this file except in compliance with the License.
7178481Sjb *
8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9178481Sjb * or http://www.opensolaris.org/os/licensing.
10178481Sjb * See the License for the specific language governing permissions
11178481Sjb * and limitations under the License.
12178481Sjb *
13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each
14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15178481Sjb * If applicable, add the following below this CDDL HEADER, with the
16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying
17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
18178481Sjb *
19178481Sjb * CDDL HEADER END
20178481Sjb */
21178481Sjb/*
22178481Sjb * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23178481Sjb * Use is subject to license terms.
24178481Sjb */
25178481Sjb
26178481Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
27178481Sjb
28178481Sjb/*
29178481Sjb * This file is a sewer.
30178481Sjb */
31178481Sjb
32178481Sjb#include <limits.h>
33178481Sjb#include <stdarg.h>
34178481Sjb#include <stdio.h>
35178481Sjb#include <assert.h>
36178481Sjb#include <strings.h>
37178481Sjb#include <setjmp.h>
38178481Sjb#include <ctype.h>
39178481Sjb#include <uts/common/sys/ctf.h>
40178481Sjb
41178481Sjb#include "ctftools.h"
42178481Sjb#include "memory.h"
43178481Sjb#include "list.h"
44178481Sjb
45178481Sjb#define	HASH(NUM)	((int)(NUM & (BUCKETS - 1)))
46178481Sjb#define	BUCKETS		128
47178481Sjb
48178481Sjb#define	TYPEPAIRMULT	10000
49178481Sjb#define	MAKETYPEID(file, num)	((file) * TYPEPAIRMULT + num)
50178481Sjb#define	TYPEFILE(tid)		((tid) / TYPEPAIRMULT)
51178481Sjb#define	TYPENUM(tid)		((tid) % TYPEPAIRMULT)
52178481Sjb
53178481Sjb#define	expected(a, b, c) _expected(a, b, c, __LINE__)
54178481Sjb
55178481Sjbstatic int faketypenumber = 100000000;
56178481Sjb
57178481Sjbstatic tdesc_t *hash_table[BUCKETS];
58178481Sjbstatic tdesc_t *name_table[BUCKETS];
59178481Sjb
60178481Sjblist_t *typedbitfldmems;
61178481Sjb
62178481Sjbstatic void reset(void);
63178481Sjbstatic jmp_buf	resetbuf;
64178481Sjb
65178481Sjbstatic char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp);
66178481Sjbstatic void enumdef(char *cp, tdesc_t **rtdp);
67178481Sjbstatic int compute_sum(const char *w);
68178481Sjb
69178481Sjbstatic char *number(char *cp, int *n);
70178481Sjbstatic char *name(char *cp, char **w);
71178481Sjbstatic char *id(char *cp, int *h);
72178481Sjbstatic char *whitesp(char *cp);
73178481Sjbstatic void addhash(tdesc_t *tdp, int num);
74178481Sjbstatic int tagadd(char *w, int h, tdesc_t *tdp);
75178481Sjbstatic char *tdefdecl(char *cp, int h, tdesc_t **rtdp);
76178481Sjbstatic char *intrinsic(char *cp, tdesc_t **rtdp);
77178481Sjbstatic char *arraydef(char *cp, tdesc_t **rtdp);
78178481Sjb
79178481Sjbint debug_parse = DEBUG_PARSE;
80178481Sjb
81178481Sjb/*PRINTFLIKE3*/
82178481Sjbstatic void
83178481Sjbparse_debug(int level, char *cp, const char *fmt, ...)
84178481Sjb{
85178481Sjb	va_list ap;
86178481Sjb	char buf[1024];
87178481Sjb	char tmp[32];
88178481Sjb	int i;
89178481Sjb
90178481Sjb	if (level > debug_level || !debug_parse)
91178481Sjb		return;
92178481Sjb
93178481Sjb	if (cp != NULL) {
94178481Sjb		for (i = 0; i < 30; i++) {
95178481Sjb			if (cp[i] == '\0')
96178481Sjb				break;
97178481Sjb			if (!iscntrl(cp[i]))
98178481Sjb				tmp[i] = cp[i];
99178481Sjb		}
100178481Sjb		tmp[i] = '\0';
101178481Sjb		(void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp);
102178481Sjb	} else {
103178481Sjb		strcpy(buf, fmt);
104178481Sjb		strcat(buf, "\n");
105178481Sjb	}
106178481Sjb
107178481Sjb	va_start(ap, fmt);
108178481Sjb	vadebug(level, buf, ap);
109178481Sjb	va_end(ap);
110178481Sjb}
111178481Sjb
112178481Sjb/* Report unexpected syntax in stabs. */
113178481Sjbstatic void
114178481Sjb_expected(
115178481Sjb	const char *who,	/* what function, or part thereof, is reporting */
116178481Sjb	const char *what,	/* what was expected */
117178481Sjb	const char *where,	/* where we were in the line of input */
118178481Sjb	int line)
119178481Sjb{
120178481Sjb	fprintf(stderr, "%s, expecting \"%s\" at \"%s\"\n", who, what, where);
121178481Sjb	fprintf(stderr, "code line: %d, file %s\n", line,
122178481Sjb	    (curhdr ? curhdr : "NO FILE"));
123178481Sjb	reset();
124178481Sjb}
125178481Sjb
126178481Sjb/*ARGSUSED*/
127178481Sjbvoid
128178481Sjbparse_init(tdata_t *td __unused)
129178481Sjb{
130178481Sjb	int i;
131178481Sjb
132178481Sjb	for (i = 0; i < BUCKETS; i++) {
133178481Sjb		hash_table[i] = NULL;
134178481Sjb		name_table[i] = NULL;
135178481Sjb	}
136178481Sjb
137178481Sjb	if (typedbitfldmems != NULL) {
138178481Sjb		list_free(typedbitfldmems, NULL, NULL);
139178481Sjb		typedbitfldmems = NULL;
140178481Sjb	}
141178481Sjb}
142178481Sjb
143178481Sjbvoid
144178481Sjbparse_finish(tdata_t *td)
145178481Sjb{
146178481Sjb	td->td_nextid = ++faketypenumber;
147178481Sjb}
148178481Sjb
149178481Sjbstatic tdesc_t *
150178481Sjbunres_new(int tid)
151178481Sjb{
152178481Sjb	tdesc_t *tdp;
153178481Sjb
154178481Sjb	tdp = xcalloc(sizeof (*tdp));
155178481Sjb	tdp->t_type = TYPEDEF_UNRES;
156178481Sjb	tdp->t_id = tid;
157178481Sjb
158178481Sjb	return (tdp);
159178481Sjb}
160178481Sjb
161178481Sjbstatic char *
162178481Sjbread_tid(char *cp, tdesc_t **tdpp)
163178481Sjb{
164178481Sjb	tdesc_t *tdp;
165178481Sjb	int tid;
166178481Sjb
167178481Sjb	cp = id(cp, &tid);
168178481Sjb
169178481Sjb	assert(tid != 0);
170178481Sjb
171178481Sjb	if (*cp == '=') {
172178481Sjb		if (!(cp = tdefdecl(cp + 1, tid, &tdp)))
173178481Sjb			return (NULL);
174178481Sjb		if (tdp->t_id && tdp->t_id != tid) {
175178481Sjb			tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
176178481Sjb
177178481Sjb			ntdp->t_type = TYPEDEF;
178178481Sjb			ntdp->t_tdesc = tdp;
179178481Sjb			tdp = ntdp;
180178481Sjb		}
181178481Sjb		addhash(tdp, tid);
182178481Sjb	} else if ((tdp = lookup(tid)) == NULL)
183178481Sjb		tdp = unres_new(tid);
184178481Sjb
185178481Sjb	*tdpp = tdp;
186178481Sjb	return (cp);
187178481Sjb}
188178481Sjb
189178481Sjbstatic iitype_t
190178481Sjbparse_fun(char *cp, iidesc_t *ii)
191178481Sjb{
192178481Sjb	iitype_t iitype = 0;
193178481Sjb	tdesc_t *tdp;
194178481Sjb	tdesc_t **args = NULL;
195178481Sjb	int nargs = 0;
196178481Sjb	int va = 0;
197178481Sjb
198178481Sjb	/*
199178481Sjb	 * name:P		prototype
200178481Sjb	 * name:F		global function
201178481Sjb	 * name:f		static function
202178481Sjb	 */
203178481Sjb	switch (*cp++) {
204178481Sjb	case 'P':
205178481Sjb		iitype = II_NOT; /* not interesting */
206178481Sjb		break;
207178481Sjb
208178481Sjb	case 'F':
209178481Sjb		iitype = II_GFUN;
210178481Sjb		break;
211178481Sjb
212178481Sjb	case 'f':
213178481Sjb		iitype = II_SFUN;
214178481Sjb		break;
215178481Sjb
216178481Sjb	default:
217178481Sjb		expected("parse_nfun", "[PfF]", cp - 1);
218178481Sjb	}
219178481Sjb
220178481Sjb	if (!(cp = read_tid(cp, &tdp)))
221178481Sjb		return (-1);
222178481Sjb
223178481Sjb	if (*cp)
224178481Sjb		args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF);
225178481Sjb
226178481Sjb	while (*cp && *++cp) {
227178481Sjb		if (*cp == '0') {
228178481Sjb			va = 1;
229178481Sjb			continue;
230178481Sjb		}
231178481Sjb
232178481Sjb		nargs++;
233178481Sjb		if (nargs > FUNCARG_DEF)
234178481Sjb			args = xrealloc(args, sizeof (tdesc_t *) * nargs);
235178481Sjb		if (!(cp = read_tid(cp, &args[nargs - 1])))
236178481Sjb			return (-1);
237178481Sjb	}
238178481Sjb
239178481Sjb	ii->ii_type = iitype;
240178481Sjb	ii->ii_dtype = tdp;
241178481Sjb	ii->ii_nargs = nargs;
242178481Sjb	ii->ii_args = args;
243178481Sjb	ii->ii_vargs = va;
244178481Sjb
245178481Sjb	return (iitype);
246178481Sjb}
247178481Sjb
248178481Sjbstatic iitype_t
249178481Sjbparse_sym(char *cp, iidesc_t *ii)
250178481Sjb{
251178481Sjb	tdesc_t *tdp;
252178481Sjb	iitype_t iitype = 0;
253178481Sjb
254178481Sjb	/*
255178481Sjb	 * name:G		global variable
256178481Sjb	 * name:S		static variable
257178481Sjb	 */
258178481Sjb	switch (*cp++) {
259178481Sjb	case 'G':
260178481Sjb		iitype = II_GVAR;
261178481Sjb		break;
262178481Sjb	case 'S':
263178481Sjb		iitype = II_SVAR;
264178481Sjb		break;
265178481Sjb	case 'p':
266178481Sjb		iitype = II_PSYM;
267178481Sjb		break;
268178481Sjb	case '(':
269178481Sjb		cp--;
270178481Sjb		/*FALLTHROUGH*/
271178481Sjb	case 'r':
272178481Sjb	case 'V':
273178481Sjb		iitype = II_NOT; /* not interesting */
274178481Sjb		break;
275178481Sjb	default:
276178481Sjb		expected("parse_sym", "[GprSV(]", cp - 1);
277178481Sjb	}
278178481Sjb
279178481Sjb	if (!(cp = read_tid(cp, &tdp)))
280178481Sjb		return (-1);
281178481Sjb
282178481Sjb	ii->ii_type = iitype;
283178481Sjb	ii->ii_dtype = tdp;
284178481Sjb
285178481Sjb	return (iitype);
286178481Sjb}
287178481Sjb
288178481Sjbstatic iitype_t
289178481Sjbparse_type(char *cp, iidesc_t *ii)
290178481Sjb{
291178481Sjb	tdesc_t *tdp, *ntdp;
292178481Sjb	int tid;
293178481Sjb
294178481Sjb	if (*cp++ != 't')
295178481Sjb		expected("parse_type", "t (type)", cp - 1);
296178481Sjb
297178481Sjb	cp = id(cp, &tid);
298178481Sjb	if ((tdp = lookup(tid)) == NULL) {
299178481Sjb		if (*cp++ != '=')
300178481Sjb			expected("parse_type", "= (definition)", cp - 1);
301178481Sjb
302178481Sjb		(void) tdefdecl(cp, tid, &tdp);
303178481Sjb
304178481Sjb		if (tdp->t_id == tid) {
305178481Sjb			assert(tdp->t_type != TYPEDEF);
306178481Sjb			assert(!lookup(tdp->t_id));
307178481Sjb
308178481Sjb			if (!streq(tdp->t_name, ii->ii_name)) {
309178481Sjb				ntdp = xcalloc(sizeof (*ntdp));
310178481Sjb				ntdp->t_name = xstrdup(ii->ii_name);
311178481Sjb				ntdp->t_type = TYPEDEF;
312178481Sjb				ntdp->t_tdesc = tdp;
313178481Sjb				tdp->t_id = faketypenumber++;
314178481Sjb				tdp = ntdp;
315178481Sjb			}
316178481Sjb		} else if (tdp->t_id == 0) {
317178481Sjb			assert(tdp->t_type == FORWARD ||
318178481Sjb			    tdp->t_type == INTRINSIC);
319178481Sjb
320178481Sjb			if (tdp->t_name && !streq(tdp->t_name, ii->ii_name)) {
321178481Sjb				ntdp = xcalloc(sizeof (*ntdp));
322178481Sjb				ntdp->t_name = xstrdup(ii->ii_name);
323178481Sjb				ntdp->t_type = TYPEDEF;
324178481Sjb				ntdp->t_tdesc = tdp;
325178481Sjb				tdp->t_id = faketypenumber++;
326178481Sjb				tdp = ntdp;
327178481Sjb			}
328178481Sjb		} else if (tdp->t_id != tid) {
329178481Sjb			ntdp = xcalloc(sizeof (*ntdp));
330178481Sjb			ntdp->t_name = xstrdup(ii->ii_name);
331178481Sjb			ntdp->t_type = TYPEDEF;
332178481Sjb			ntdp->t_tdesc = tdp;
333178481Sjb			tdp = ntdp;
334178481Sjb		}
335178481Sjb
336178481Sjb		if (tagadd(ii->ii_name, tid, tdp) < 0)
337178481Sjb			return (-1);
338178481Sjb	}
339178481Sjb
340178481Sjb	ii->ii_type = II_TYPE;
341178481Sjb	ii->ii_dtype = tdp;
342178481Sjb	return (II_TYPE);
343178481Sjb}
344178481Sjb
345178481Sjbstatic iitype_t
346178481Sjbparse_sou(char *cp, iidesc_t *idp)
347178481Sjb{
348178481Sjb	tdesc_t *rtdp;
349178481Sjb	int tid;
350178481Sjb
351178481Sjb	if (*cp++ != 'T')
352178481Sjb		expected("parse_sou", "T (sou)", cp - 1);
353178481Sjb
354178481Sjb	cp = id(cp, &tid);
355178481Sjb	if (*cp++ != '=')
356178481Sjb		expected("parse_sou", "= (definition)", cp - 1);
357178481Sjb
358178481Sjb	parse_debug(1, NULL, "parse_sou: declaring '%s'", idp->ii_name ?
359178481Sjb	    idp->ii_name : "(anon)");
360178481Sjb	if ((rtdp = lookup(tid)) != NULL) {
361178481Sjb		if (idp->ii_name != NULL) {
362178481Sjb			if (rtdp->t_name != NULL &&
363178481Sjb			    strcmp(rtdp->t_name, idp->ii_name) != 0) {
364178481Sjb				tdesc_t *tdp;
365178481Sjb
366178481Sjb				tdp = xcalloc(sizeof (*tdp));
367178481Sjb				tdp->t_name = xstrdup(idp->ii_name);
368178481Sjb				tdp->t_type = TYPEDEF;
369178481Sjb				tdp->t_tdesc = rtdp;
370178481Sjb				addhash(tdp, tid); /* for *(x,y) types */
371178481Sjb				parse_debug(3, NULL, "    %s defined as %s(%d)",
372178481Sjb				    idp->ii_name, tdesc_name(rtdp), tid);
373178481Sjb			} else if (rtdp->t_name == NULL) {
374178481Sjb				rtdp->t_name = xstrdup(idp->ii_name);
375178481Sjb				addhash(rtdp, tid);
376178481Sjb			}
377178481Sjb		}
378178481Sjb	} else {
379178481Sjb		rtdp = xcalloc(sizeof (*rtdp));
380178481Sjb		rtdp->t_name = idp->ii_name ? xstrdup(idp->ii_name) : NULL;
381178481Sjb		addhash(rtdp, tid);
382178481Sjb	}
383178481Sjb
384178481Sjb	switch (*cp++) {
385178481Sjb	case 's':
386178481Sjb		(void) soudef(cp, STRUCT, &rtdp);
387178481Sjb		break;
388178481Sjb	case 'u':
389178481Sjb		(void) soudef(cp, UNION, &rtdp);
390178481Sjb		break;
391178481Sjb	case 'e':
392178481Sjb		enumdef(cp, &rtdp);
393178481Sjb		break;
394178481Sjb	default:
395178481Sjb		expected("parse_sou", "<tag type s/u/e>", cp - 1);
396178481Sjb		break;
397178481Sjb	}
398178481Sjb
399178481Sjb	idp->ii_type = II_SOU;
400178481Sjb	idp->ii_dtype = rtdp;
401178481Sjb	return (II_SOU);
402178481Sjb}
403178481Sjb
404178481Sjbint
405178481Sjbparse_stab(stab_t *stab, char *cp, iidesc_t **iidescp)
406178481Sjb{
407178481Sjb	iidesc_t *ii = NULL;
408178481Sjb	iitype_t (*parse)(char *, iidesc_t *);
409178481Sjb	int rc;
410178481Sjb
411178481Sjb	/*
412178481Sjb	 * set up for reset()
413178481Sjb	 */
414178481Sjb	if (setjmp(resetbuf))
415178481Sjb		return (-1);
416178481Sjb
417178481Sjb	cp = whitesp(cp);
418178481Sjb	ii = iidesc_new(NULL);
419178481Sjb	cp = name(cp, &ii->ii_name);
420178481Sjb
421178481Sjb	switch (stab->n_type) {
422178481Sjb	case N_FUN:
423178481Sjb		parse = parse_fun;
424178481Sjb		break;
425178481Sjb
426178481Sjb	case N_LSYM:
427178481Sjb		if (*cp == 't')
428178481Sjb			parse = parse_type;
429178481Sjb		else if (*cp == 'T')
430178481Sjb			parse = parse_sou;
431178481Sjb		else
432178481Sjb			parse = parse_sym;
433178481Sjb		break;
434178481Sjb
435178481Sjb	case N_GSYM:
436178481Sjb	case N_LCSYM:
437178481Sjb	case N_PSYM:
438178481Sjb	case N_ROSYM:
439178481Sjb	case N_RSYM:
440178481Sjb	case N_STSYM:
441178481Sjb		parse = parse_sym;
442178481Sjb		break;
443178481Sjb	default:
444178481Sjb		parse_debug(1, cp, "Unknown stab type %#x", stab->n_type);
445178481Sjb		bzero(&resetbuf, sizeof (resetbuf));
446178481Sjb		return (-1);
447178481Sjb	}
448178481Sjb
449178481Sjb	rc = parse(cp, ii);
450178481Sjb	bzero(&resetbuf, sizeof (resetbuf));
451178481Sjb
452178481Sjb	if (rc < 0 || ii->ii_type == II_NOT) {
453178481Sjb		iidesc_free(ii, NULL);
454178481Sjb		return (rc);
455178481Sjb	}
456178481Sjb
457178481Sjb	*iidescp = ii;
458178481Sjb
459178481Sjb	return (1);
460178481Sjb}
461178481Sjb
462178481Sjb/*
463178481Sjb * Check if we have this node in the hash table already
464178481Sjb */
465178481Sjbtdesc_t *
466178481Sjblookup(int h)
467178481Sjb{
468178481Sjb	int bucket = HASH(h);
469178481Sjb	tdesc_t *tdp = hash_table[bucket];
470178481Sjb
471178481Sjb	while (tdp != NULL) {
472178481Sjb		if (tdp->t_id == h)
473178481Sjb			return (tdp);
474178481Sjb		tdp = tdp->t_hash;
475178481Sjb	}
476178481Sjb	return (NULL);
477178481Sjb}
478178481Sjb
479178481Sjbstatic char *
480178481Sjbwhitesp(char *cp)
481178481Sjb{
482178481Sjb	char c;
483178481Sjb
484178481Sjb	for (c = *cp++; isspace(c); c = *cp++);
485178481Sjb	--cp;
486178481Sjb	return (cp);
487178481Sjb}
488178481Sjb
489178481Sjbstatic char *
490178481Sjbname(char *cp, char **w)
491178481Sjb{
492178481Sjb	char *new, *orig, c;
493178481Sjb	int len;
494178481Sjb
495178481Sjb	orig = cp;
496178481Sjb	c = *cp++;
497178481Sjb	if (c == ':')
498178481Sjb		*w = NULL;
499178481Sjb	else if (isalpha(c) || strchr("_.$", c)) {
500178481Sjb		for (c = *cp++; isalnum(c) || strchr(" _.$", c); c = *cp++)
501178481Sjb			;
502178481Sjb		if (c != ':')
503178481Sjb			reset();
504178481Sjb		len = cp - orig;
505178481Sjb		new = xmalloc(len);
506178481Sjb		while (orig < cp - 1)
507178481Sjb			*new++ = *orig++;
508178481Sjb		*new = '\0';
509178481Sjb		*w = new - (len - 1);
510178481Sjb	} else
511178481Sjb		reset();
512178481Sjb
513178481Sjb	return (cp);
514178481Sjb}
515178481Sjb
516178481Sjbstatic char *
517178481Sjbnumber(char *cp, int *n)
518178481Sjb{
519178481Sjb	char *next;
520178481Sjb
521178481Sjb	*n = (int)strtol(cp, &next, 10);
522178481Sjb	if (next == cp)
523178481Sjb		expected("number", "<number>", cp);
524178481Sjb	return (next);
525178481Sjb}
526178481Sjb
527178481Sjbstatic char *
528178481Sjbid(char *cp, int *h)
529178481Sjb{
530178481Sjb	int n1, n2;
531178481Sjb
532178481Sjb	if (*cp == '(') {	/* SunPro style */
533178481Sjb		cp++;
534178481Sjb		cp = number(cp, &n1);
535178481Sjb		if (*cp++ != ',')
536178481Sjb			expected("id", ",", cp - 1);
537178481Sjb		cp = number(cp, &n2);
538178481Sjb		if (*cp++ != ')')
539178481Sjb			expected("id", ")", cp - 1);
540178481Sjb		*h = MAKETYPEID(n1, n2);
541178481Sjb	} else if (isdigit(*cp)) { /* gcc style */
542178481Sjb		cp = number(cp, &n1);
543178481Sjb		*h = n1;
544178481Sjb	} else {
545178481Sjb		expected("id", "(/0-9", cp);
546178481Sjb	}
547178481Sjb	return (cp);
548178481Sjb}
549178481Sjb
550178481Sjbstatic int
551178481Sjbtagadd(char *w, int h, tdesc_t *tdp)
552178481Sjb{
553178481Sjb	tdesc_t *otdp;
554178481Sjb
555178481Sjb	tdp->t_name = w;
556178481Sjb	if (!(otdp = lookup(h)))
557178481Sjb		addhash(tdp, h);
558178481Sjb	else if (otdp != tdp) {
559178481Sjb		warning("duplicate entry\n");
560178481Sjb		warning("  old: %s %d (%d,%d)\n", tdesc_name(otdp),
561178481Sjb		    otdp->t_type, TYPEFILE(otdp->t_id), TYPENUM(otdp->t_id));
562178481Sjb		warning("  new: %s %d (%d,%d)\n", tdesc_name(tdp),
563178481Sjb		    tdp->t_type, TYPEFILE(tdp->t_id), TYPENUM(tdp->t_id));
564178481Sjb		return (-1);
565178481Sjb	}
566178481Sjb
567178481Sjb	return (0);
568178481Sjb}
569178481Sjb
570178481Sjbstatic char *
571178481Sjbtdefdecl(char *cp, int h, tdesc_t **rtdp)
572178481Sjb{
573178481Sjb	tdesc_t *ntdp;
574178481Sjb	char *w;
575178481Sjb	int c, h2;
576178481Sjb	char type;
577178481Sjb
578178481Sjb	parse_debug(3, cp, "tdefdecl h=%d", h);
579178481Sjb
580178481Sjb	/* Type codes */
581178481Sjb	switch (type = *cp) {
582178481Sjb	case 'b': /* integer */
583178481Sjb	case 'R': /* fp */
584178481Sjb		cp = intrinsic(cp, rtdp);
585178481Sjb		break;
586178481Sjb	case '(': /* equiv to another type */
587178481Sjb		cp = id(cp, &h2);
588178481Sjb		ntdp = lookup(h2);
589178481Sjb
590178481Sjb		if (ntdp != NULL && *cp == '=') {
591178481Sjb			if (ntdp->t_type == FORWARD && *(cp + 1) == 'x') {
592178481Sjb				/*
593178481Sjb				 * The 6.2 compiler, and possibly others, will
594178481Sjb				 * sometimes emit the same stab for a forward
595178481Sjb				 * declaration twice.  That is, "(1,2)=xsfoo:"
596178481Sjb				 * will sometimes show up in two different
597178481Sjb				 * places.  This is, of course, quite fun.  We
598178481Sjb				 * want CTF to work in spite of the compiler,
599178481Sjb				 * so we'll let this one through.
600178481Sjb				 */
601178481Sjb				char *c2 = cp + 2;
602178481Sjb				char *nm;
603178481Sjb
604178481Sjb				if (!strchr("sue", *c2++)) {
605178481Sjb					expected("tdefdecl/x-redefine", "[sue]",
606178481Sjb					    c2 - 1);
607178481Sjb				}
608178481Sjb
609178481Sjb				c2 = name(c2, &nm);
610178481Sjb				if (strcmp(nm, ntdp->t_name) != 0) {
611178481Sjb					terminate("Stabs error: Attempt to "
612178481Sjb					    "redefine type (%d,%d) as "
613178481Sjb					    "something else: %s\n",
614178481Sjb					    TYPEFILE(h2), TYPENUM(h2),
615178481Sjb					    c2 - 1);
616178481Sjb				}
617178481Sjb				free(nm);
618178481Sjb
619178481Sjb				h2 = faketypenumber++;
620178481Sjb				ntdp = NULL;
621178481Sjb			} else {
622178481Sjb				terminate("Stabs error: Attempting to "
623178481Sjb				    "redefine type (%d,%d)\n", TYPEFILE(h2),
624178481Sjb				    TYPENUM(h2));
625178481Sjb			}
626178481Sjb		}
627178481Sjb
628178481Sjb		if (ntdp == NULL) {  /* if that type isn't defined yet */
629178481Sjb			if (*cp != '=') {
630178481Sjb				/* record it as unresolved */
631178481Sjb				parse_debug(3, NULL, "tdefdecl unres type %d",
632178481Sjb				    h2);
633178481Sjb				*rtdp = calloc(sizeof (**rtdp), 1);
634178481Sjb				(*rtdp)->t_type = TYPEDEF_UNRES;
635178481Sjb				(*rtdp)->t_id = h2;
636178481Sjb				break;
637178481Sjb			} else
638178481Sjb				cp++;
639178481Sjb
640178481Sjb			/* define a new type */
641178481Sjb			cp = tdefdecl(cp, h2, rtdp);
642178481Sjb			if ((*rtdp)->t_id && (*rtdp)->t_id != h2) {
643178481Sjb				ntdp = calloc(sizeof (*ntdp), 1);
644178481Sjb				ntdp->t_type = TYPEDEF;
645178481Sjb				ntdp->t_tdesc = *rtdp;
646178481Sjb				*rtdp = ntdp;
647178481Sjb			}
648178481Sjb
649178481Sjb			addhash(*rtdp, h2);
650178481Sjb
651178481Sjb		} else { /* that type is already defined */
652178481Sjb			if (ntdp->t_type != TYPEDEF || ntdp->t_name != NULL) {
653178481Sjb				*rtdp = ntdp;
654178481Sjb			} else {
655178481Sjb				parse_debug(3, NULL,
656178481Sjb				    "No duplicate typedef anon for ref");
657178481Sjb				*rtdp = ntdp;
658178481Sjb			}
659178481Sjb		}
660178481Sjb		break;
661178481Sjb	case '*':
662178481Sjb		ntdp = NULL;
663178481Sjb		cp = tdefdecl(cp + 1, h, &ntdp);
664178481Sjb		if (ntdp == NULL)
665178481Sjb			expected("tdefdecl/*", "id", cp);
666178481Sjb
667178481Sjb		if (!ntdp->t_id)
668178481Sjb			ntdp->t_id = faketypenumber++;
669178481Sjb
670178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
671178481Sjb		(*rtdp)->t_type = POINTER;
672178481Sjb		(*rtdp)->t_size = 0;
673178481Sjb		(*rtdp)->t_id = h;
674178481Sjb		(*rtdp)->t_tdesc = ntdp;
675178481Sjb		break;
676178481Sjb	case 'f':
677178481Sjb		cp = tdefdecl(cp + 1, h, &ntdp);
678178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
679178481Sjb		(*rtdp)->t_type = FUNCTION;
680178481Sjb		(*rtdp)->t_size = 0;
681178481Sjb		(*rtdp)->t_id = h;
682178481Sjb		(*rtdp)->t_fndef = xcalloc(sizeof (fndef_t));
683178481Sjb		/*
684178481Sjb		 * The 6.1 compiler will sometimes generate incorrect stabs for
685178481Sjb		 * function pointers (it'll get the return type wrong).  This
686178481Sjb		 * causes merges to fail.  We therefore treat function pointers
687178481Sjb		 * as if they all point to functions that return int.  When
688178481Sjb		 * 4432549 is fixed, the lookupname() call below should be
689178481Sjb		 * replaced with `ntdp'.
690178481Sjb		 */
691178481Sjb		(*rtdp)->t_fndef->fn_ret = lookupname("int");
692178481Sjb		break;
693178481Sjb	case 'a':
694178481Sjb	case 'z':
695178481Sjb		cp++;
696178481Sjb		if (*cp++ != 'r')
697178481Sjb			expected("tdefdecl/[az]", "r", cp - 1);
698178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
699178481Sjb		(*rtdp)->t_type = ARRAY;
700178481Sjb		(*rtdp)->t_id = h;
701178481Sjb		cp = arraydef(cp, rtdp);
702178481Sjb		break;
703178481Sjb	case 'x':
704178481Sjb		c = *++cp;
705178481Sjb		if (c != 's' && c != 'u' && c != 'e')
706178481Sjb			expected("tdefdecl/x", "[sue]", cp - 1);
707178481Sjb		cp = name(cp + 1, &w);
708178481Sjb
709178481Sjb		ntdp = xcalloc(sizeof (*ntdp));
710178481Sjb		ntdp->t_type = FORWARD;
711178481Sjb		ntdp->t_name = w;
712178481Sjb		/*
713178481Sjb		 * We explicitly don't set t_id here - the caller will do it.
714178481Sjb		 * The caller may want to use a real type ID, or they may
715178481Sjb		 * choose to make one up.
716178481Sjb		 */
717178481Sjb
718178481Sjb		*rtdp = ntdp;
719178481Sjb		break;
720178481Sjb
721178481Sjb	case 'B': /* volatile */
722178481Sjb		cp = tdefdecl(cp + 1, h, &ntdp);
723178481Sjb
724178481Sjb		if (!ntdp->t_id)
725178481Sjb			ntdp->t_id = faketypenumber++;
726178481Sjb
727178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
728178481Sjb		(*rtdp)->t_type = VOLATILE;
729178481Sjb		(*rtdp)->t_size = 0;
730178481Sjb		(*rtdp)->t_tdesc = ntdp;
731178481Sjb		(*rtdp)->t_id = h;
732178481Sjb		break;
733178481Sjb
734178481Sjb	case 'k': /* const */
735178481Sjb		cp = tdefdecl(cp + 1, h, &ntdp);
736178481Sjb
737178481Sjb		if (!ntdp->t_id)
738178481Sjb			ntdp->t_id = faketypenumber++;
739178481Sjb
740178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
741178481Sjb		(*rtdp)->t_type = CONST;
742178481Sjb		(*rtdp)->t_size = 0;
743178481Sjb		(*rtdp)->t_tdesc = ntdp;
744178481Sjb		(*rtdp)->t_id = h;
745178481Sjb		break;
746178481Sjb
747178481Sjb	case 'K': /* restricted */
748178481Sjb		cp = tdefdecl(cp + 1, h, &ntdp);
749178481Sjb
750178481Sjb		if (!ntdp->t_id)
751178481Sjb			ntdp->t_id = faketypenumber++;
752178481Sjb
753178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
754178481Sjb		(*rtdp)->t_type = RESTRICT;
755178481Sjb		(*rtdp)->t_size = 0;
756178481Sjb		(*rtdp)->t_tdesc = ntdp;
757178481Sjb		(*rtdp)->t_id = h;
758178481Sjb		break;
759178481Sjb
760178481Sjb	case 'u':
761178481Sjb	case 's':
762178481Sjb		cp++;
763178481Sjb
764178481Sjb		*rtdp = xcalloc(sizeof (**rtdp));
765178481Sjb		(*rtdp)->t_name = NULL;
766178481Sjb		cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
767178481Sjb		break;
768178481Sjb	default:
769178481Sjb		expected("tdefdecl", "<type code>", cp);
770178481Sjb	}
771178481Sjb	return (cp);
772178481Sjb}
773178481Sjb
774178481Sjbstatic char *
775178481Sjbintrinsic(char *cp, tdesc_t **rtdp)
776178481Sjb{
777178481Sjb	intr_t *intr = xcalloc(sizeof (intr_t));
778178481Sjb	tdesc_t *tdp;
779178481Sjb	int width, fmt, i;
780178481Sjb
781178481Sjb	switch (*cp++) {
782178481Sjb	case 'b':
783178481Sjb		intr->intr_type = INTR_INT;
784178481Sjb		if (*cp == 's')
785178481Sjb			intr->intr_signed = 1;
786178481Sjb		else if (*cp != 'u')
787178481Sjb			expected("intrinsic/b", "[su]", cp);
788178481Sjb		cp++;
789178481Sjb
790178481Sjb		if (strchr("cbv", *cp))
791178481Sjb			intr->intr_iformat = *cp++;
792178481Sjb
793178481Sjb		cp = number(cp, &width);
794178481Sjb		if (*cp++ != ';')
795178481Sjb			expected("intrinsic/b", "; (post-width)", cp - 1);
796178481Sjb
797178481Sjb		cp = number(cp, &intr->intr_offset);
798178481Sjb		if (*cp++ != ';')
799178481Sjb			expected("intrinsic/b", "; (post-offset)", cp - 1);
800178481Sjb
801178481Sjb		cp = number(cp, &intr->intr_nbits);
802178481Sjb		break;
803178481Sjb
804178481Sjb	case 'R':
805178481Sjb		intr->intr_type = INTR_REAL;
806178481Sjb		for (fmt = 0, i = 0; isdigit(*(cp + i)); i++)
807178481Sjb			fmt = fmt * 10 + (*(cp + i) - '0');
808178481Sjb
809178481Sjb		if (fmt < 1 || fmt > CTF_FP_MAX)
810178481Sjb			expected("intrinsic/R", "number <= CTF_FP_MAX", cp);
811178481Sjb
812178481Sjb		intr->intr_fformat = fmt;
813178481Sjb		cp += i;
814178481Sjb
815178481Sjb		if (*cp++ != ';')
816178481Sjb			expected("intrinsic/R", ";", cp - 1);
817178481Sjb		cp = number(cp, &width);
818178481Sjb
819178481Sjb		intr->intr_nbits = width * 8;
820178481Sjb		break;
821178481Sjb	}
822178481Sjb
823178481Sjb	tdp = xcalloc(sizeof (*tdp));
824178481Sjb	tdp->t_type = INTRINSIC;
825178481Sjb	tdp->t_size = width;
826178481Sjb	tdp->t_name = NULL;
827178481Sjb	tdp->t_intr = intr;
828178481Sjb	parse_debug(3, NULL, "intrinsic: size=%d", width);
829178481Sjb	*rtdp = tdp;
830178481Sjb
831178481Sjb	return (cp);
832178481Sjb}
833178481Sjb
834178481Sjbstatic tdesc_t *
835178481Sjbbitintrinsic(tdesc_t *template, int nbits)
836178481Sjb{
837178481Sjb	tdesc_t *newtdp = xcalloc(sizeof (tdesc_t));
838178481Sjb
839178481Sjb	newtdp->t_name = xstrdup(template->t_name);
840178481Sjb	newtdp->t_id = faketypenumber++;
841178481Sjb	newtdp->t_type = INTRINSIC;
842178481Sjb	newtdp->t_size = template->t_size;
843178481Sjb	newtdp->t_intr = xmalloc(sizeof (intr_t));
844178481Sjb	bcopy(template->t_intr, newtdp->t_intr, sizeof (intr_t));
845178481Sjb	newtdp->t_intr->intr_nbits = nbits;
846178481Sjb
847178481Sjb	return (newtdp);
848178481Sjb}
849178481Sjb
850178481Sjbstatic char *
851178481Sjboffsize(char *cp, mlist_t *mlp)
852178481Sjb{
853178481Sjb	int offset, size;
854178481Sjb
855178481Sjb	if (*cp == ',')
856178481Sjb		cp++;
857178481Sjb	cp = number(cp, &offset);
858178481Sjb	if (*cp++ != ',')
859178481Sjb		expected("offsize/2", ",", cp - 1);
860178481Sjb	cp = number(cp, &size);
861178481Sjb	if (*cp++ != ';')
862178481Sjb		expected("offsize/3", ";", cp - 1);
863178481Sjb	mlp->ml_offset = offset;
864178481Sjb	mlp->ml_size = size;
865178481Sjb	return (cp);
866178481Sjb}
867178481Sjb
868178481Sjbstatic tdesc_t *
869178481Sjbfind_intrinsic(tdesc_t *tdp)
870178481Sjb{
871178481Sjb	for (;;) {
872178481Sjb		switch (tdp->t_type) {
873178481Sjb		case TYPEDEF:
874178481Sjb		case VOLATILE:
875178481Sjb		case CONST:
876178481Sjb		case RESTRICT:
877178481Sjb			tdp = tdp->t_tdesc;
878178481Sjb			break;
879178481Sjb
880178481Sjb		default:
881178481Sjb			return (tdp);
882178481Sjb		}
883178481Sjb	}
884178481Sjb}
885178481Sjb
886178481Sjbstatic char *
887178481Sjbsoudef(char *cp, stabtype_t type, tdesc_t **rtdp)
888178481Sjb{
889178481Sjb	mlist_t *mlp, **prev;
890178481Sjb	char *w;
891178481Sjb	int h;
892178481Sjb	int size;
893178481Sjb	tdesc_t *tdp, *itdp;
894178481Sjb
895178481Sjb	cp = number(cp, &size);
896178481Sjb	(*rtdp)->t_size = size;
897178481Sjb	(*rtdp)->t_type = type; /* s or u */
898178481Sjb
899178481Sjb	/*
900178481Sjb	 * An '@' here indicates a bitmask follows.   This is so the
901178481Sjb	 * compiler can pass information to debuggers about how structures
902178481Sjb	 * are passed in the v9 world.  We don't need this information
903178481Sjb	 * so we skip over it.
904178481Sjb	 */
905178481Sjb	if (cp[0] == '@') {
906178481Sjb		cp += 3;
907178481Sjb	}
908178481Sjb
909178481Sjb	parse_debug(3, cp, "soudef: %s size=%d", tdesc_name(*rtdp),
910178481Sjb	    (*rtdp)->t_size);
911178481Sjb
912178481Sjb	prev = &((*rtdp)->t_members);
913178481Sjb	/* now fill up the fields */
914178481Sjb	while ((*cp != '\0') && (*cp != ';')) { /* signifies end of fields */
915178481Sjb		mlp = xcalloc(sizeof (*mlp));
916178481Sjb		*prev = mlp;
917178481Sjb		cp = name(cp, &w);
918178481Sjb		mlp->ml_name = w;
919178481Sjb		cp = id(cp, &h);
920178481Sjb		/*
921178481Sjb		 * find the tdesc struct in the hash table for this type
922178481Sjb		 * and stick a ptr in here
923178481Sjb		 */
924178481Sjb		tdp = lookup(h);
925178481Sjb		if (tdp == NULL) { /* not in hash list */
926178481Sjb			parse_debug(3, NULL, "      defines %s (%d)", w, h);
927178481Sjb			if (*cp++ != '=') {
928178481Sjb				tdp = unres_new(h);
929178481Sjb				parse_debug(3, NULL,
930178481Sjb				    "      refers to %s (unresolved %d)",
931178481Sjb				    (w ? w : "anon"), h);
932178481Sjb			} else {
933178481Sjb				cp = tdefdecl(cp, h, &tdp);
934178481Sjb
935178481Sjb				if (tdp->t_id && tdp->t_id != h) {
936178481Sjb					tdesc_t *ntdp = xcalloc(sizeof (*ntdp));
937178481Sjb
938178481Sjb					ntdp->t_type = TYPEDEF;
939178481Sjb					ntdp->t_tdesc = tdp;
940178481Sjb					tdp = ntdp;
941178481Sjb				}
942178481Sjb
943178481Sjb				addhash(tdp, h);
944178481Sjb				parse_debug(4, cp,
945178481Sjb				    "     soudef now looking at    ");
946178481Sjb				cp++;
947178481Sjb			}
948178481Sjb		} else {
949178481Sjb			parse_debug(3, NULL, "      refers to %s (%d, %s)",
950178481Sjb			    w ? w : "anon", h, tdesc_name(tdp));
951178481Sjb		}
952178481Sjb
953178481Sjb		cp = offsize(cp, mlp);
954178481Sjb
955178481Sjb		itdp = find_intrinsic(tdp);
956178481Sjb		if (itdp->t_type == INTRINSIC) {
957178481Sjb			if (mlp->ml_size != itdp->t_intr->intr_nbits) {
958178481Sjb				parse_debug(4, cp, "making %d bit intrinsic "
959178481Sjb				    "from %s", mlp->ml_size, tdesc_name(itdp));
960178481Sjb				mlp->ml_type = bitintrinsic(itdp, mlp->ml_size);
961178481Sjb			} else
962178481Sjb				mlp->ml_type = tdp;
963178481Sjb		} else if (itdp->t_type == TYPEDEF_UNRES) {
964178481Sjb			list_add(&typedbitfldmems, mlp);
965178481Sjb			mlp->ml_type = tdp;
966178481Sjb		} else {
967178481Sjb			mlp->ml_type = tdp;
968178481Sjb		}
969178481Sjb
970178481Sjb		/* cp is now pointing to next field */
971178481Sjb		prev = &mlp->ml_next;
972178481Sjb	}
973178481Sjb	return (cp);
974178481Sjb}
975178481Sjb
976178481Sjbstatic char *
977178481Sjbarraydef(char *cp, tdesc_t **rtdp)
978178481Sjb{
979178481Sjb	int start, end, h;
980178481Sjb
981178481Sjb	cp = id(cp, &h);
982178481Sjb	if (*cp++ != ';')
983178481Sjb		expected("arraydef/1", ";", cp - 1);
984178481Sjb
985178481Sjb	(*rtdp)->t_ardef = xcalloc(sizeof (ardef_t));
986178481Sjb	(*rtdp)->t_ardef->ad_idxtype = lookup(h);
987178481Sjb
988178481Sjb	cp = number(cp, &start); /* lower */
989178481Sjb	if (*cp++ != ';')
990178481Sjb		expected("arraydef/2", ";", cp - 1);
991178481Sjb
992178481Sjb	if (*cp == 'S') {
993178481Sjb		/* variable length array - treat as null dimensioned */
994178481Sjb		cp++;
995178481Sjb		if (*cp++ != '-')
996178481Sjb			expected("arraydef/fpoff-sep", "-", cp - 1);
997178481Sjb		cp = number(cp, &end);
998178481Sjb		end = start;
999178481Sjb	} else {
1000178481Sjb		/* normal fixed-dimension array */
1001178481Sjb		cp = number(cp, &end);  /* upper */
1002178481Sjb	}
1003178481Sjb
1004178481Sjb	if (*cp++ != ';')
1005178481Sjb		expected("arraydef/3", ";", cp - 1);
1006178481Sjb	(*rtdp)->t_ardef->ad_nelems = end - start + 1;
1007178481Sjb	cp = tdefdecl(cp, h, &((*rtdp)->t_ardef->ad_contents));
1008178481Sjb
1009178481Sjb	parse_debug(3, cp, "defined array idx type %d %d-%d next ",
1010178481Sjb	    h, start, end);
1011178481Sjb
1012178481Sjb	return (cp);
1013178481Sjb}
1014178481Sjb
1015178481Sjbstatic void
1016178481Sjbenumdef(char *cp, tdesc_t **rtdp)
1017178481Sjb{
1018178481Sjb	elist_t *elp, **prev;
1019178481Sjb	char *w;
1020178481Sjb
1021178481Sjb	(*rtdp)->t_type = ENUM;
1022178481Sjb	(*rtdp)->t_emem = NULL;
1023178481Sjb
1024178481Sjb	prev = &((*rtdp)->t_emem);
1025178481Sjb	while (*cp != ';') {
1026178481Sjb		elp = xcalloc(sizeof (*elp));
1027178481Sjb		elp->el_next = NULL;
1028178481Sjb		*prev = elp;
1029178481Sjb		cp = name(cp, &w);
1030178481Sjb		elp->el_name = w;
1031178481Sjb		cp = number(cp, &elp->el_number);
1032178481Sjb		parse_debug(3, NULL, "enum %s: %s=%d", tdesc_name(*rtdp),
1033178481Sjb		    elp->el_name, elp->el_number);
1034178481Sjb		prev = &elp->el_next;
1035178481Sjb		if (*cp++ != ',')
1036178481Sjb			expected("enumdef", ",", cp - 1);
1037178481Sjb	}
1038178481Sjb}
1039178481Sjb
1040178481Sjbstatic tdesc_t *
1041178481Sjblookup_name(tdesc_t **hash, const char *name1)
1042178481Sjb{
1043178481Sjb	int bucket = compute_sum(name1);
1044178481Sjb	tdesc_t *tdp, *ttdp = NULL;
1045178481Sjb
1046178481Sjb	for (tdp = hash[bucket]; tdp != NULL; tdp = tdp->t_next) {
1047178481Sjb		if (tdp->t_name != NULL && strcmp(tdp->t_name, name1) == 0) {
1048178481Sjb			if (tdp->t_type == STRUCT || tdp->t_type == UNION ||
1049178481Sjb			    tdp->t_type == ENUM || tdp->t_type == INTRINSIC)
1050178481Sjb				return (tdp);
1051178481Sjb			if (tdp->t_type == TYPEDEF)
1052178481Sjb				ttdp = tdp;
1053178481Sjb		}
1054178481Sjb	}
1055178481Sjb	return (ttdp);
1056178481Sjb}
1057178481Sjb
1058178481Sjbtdesc_t *
1059178481Sjblookupname(const char *name1)
1060178481Sjb{
1061178481Sjb	return (lookup_name(name_table, name1));
1062178481Sjb}
1063178481Sjb
1064178481Sjb/*
1065178481Sjb * Add a node to the hash queues.
1066178481Sjb */
1067178481Sjbstatic void
1068178481Sjbaddhash(tdesc_t *tdp, int num)
1069178481Sjb{
1070178481Sjb	int hash = HASH(num);
1071178481Sjb	tdesc_t *ttdp;
1072178481Sjb	char added_num = 0, added_name = 0;
1073178481Sjb
1074178481Sjb	/*
1075178481Sjb	 * If it already exists in the hash table don't add it again
1076178481Sjb	 * (but still check to see if the name should be hashed).
1077178481Sjb	 */
1078178481Sjb	ttdp = lookup(num);
1079178481Sjb
1080178481Sjb	if (ttdp == NULL) {
1081178481Sjb		tdp->t_id = num;
1082178481Sjb		tdp->t_hash = hash_table[hash];
1083178481Sjb		hash_table[hash] = tdp;
1084178481Sjb		added_num = 1;
1085178481Sjb	}
1086178481Sjb
1087178481Sjb	if (tdp->t_name != NULL) {
1088178481Sjb		ttdp = lookupname(tdp->t_name);
1089178481Sjb		if (ttdp == NULL) {
1090178481Sjb			hash = compute_sum(tdp->t_name);
1091178481Sjb			tdp->t_next = name_table[hash];
1092178481Sjb			name_table[hash] = tdp;
1093178481Sjb			added_name = 1;
1094178481Sjb		}
1095178481Sjb	}
1096178481Sjb	if (!added_num && !added_name) {
1097178481Sjb		terminate("stabs: broken hash\n");
1098178481Sjb	}
1099178481Sjb}
1100178481Sjb
1101178481Sjbstatic int
1102178481Sjbcompute_sum(const char *w)
1103178481Sjb{
1104178481Sjb	char c;
1105178481Sjb	int sum;
1106178481Sjb
1107178481Sjb	for (sum = 0; (c = *w) != '\0'; sum += c, w++)
1108178481Sjb		;
1109178481Sjb	return (HASH(sum));
1110178481Sjb}
1111178481Sjb
1112178481Sjbstatic void
1113178481Sjbreset(void)
1114178481Sjb{
1115178481Sjb	longjmp(resetbuf, 1);
1116178481Sjb}
1117178481Sjb
1118178481Sjbvoid
1119178481Sjbcheck_hash(void)
1120178481Sjb{
1121178481Sjb	tdesc_t *tdp;
1122178481Sjb	int i;
1123178481Sjb
1124178481Sjb	printf("checking hash\n");
1125178481Sjb	for (i = 0; i < BUCKETS; i++) {
1126178481Sjb		if (hash_table[i]) {
1127178481Sjb			for (tdp = hash_table[i]->t_hash;
1128178481Sjb			    tdp && tdp != hash_table[i];
1129178481Sjb			    tdp = tdp->t_hash)
1130178481Sjb				continue;
1131178481Sjb			if (tdp) {
1132178481Sjb				terminate("cycle in hash bucket %d\n", i);
1133178481Sjb				return;
1134178481Sjb			}
1135178481Sjb		}
1136178481Sjb
1137178481Sjb		if (name_table[i]) {
1138178481Sjb			for (tdp = name_table[i]->t_next;
1139178481Sjb			    tdp && tdp != name_table[i];
1140178481Sjb			    tdp = tdp->t_next)
1141178481Sjb				continue;
1142178481Sjb			if (tdp) {
1143178481Sjb				terminate("cycle in name bucket %d\n", i);
1144178481Sjb				return;
1145178481Sjb			}
1146178481Sjb		}
1147178481Sjb	}
1148178481Sjb	printf("done\n");
1149178481Sjb}
1150178481Sjb
1151178481Sjb/*ARGSUSED1*/
1152178481Sjbstatic int
1153178481Sjbresolve_typed_bitfields_cb(void *arg, void *private __unused)
1154178481Sjb{
1155178481Sjb	mlist_t *ml = arg;
1156178481Sjb	tdesc_t *tdp = ml->ml_type;
1157178481Sjb
1158178481Sjb	debug(3, "Resolving typed bitfields (member %s)\n",
1159178481Sjb	    (ml->ml_name ? ml->ml_name : "(anon)"));
1160178481Sjb
1161178481Sjb	while (tdp) {
1162178481Sjb		switch (tdp->t_type) {
1163178481Sjb		case INTRINSIC:
1164178481Sjb			if (ml->ml_size != tdp->t_intr->intr_nbits) {
1165178481Sjb				debug(3, "making %d bit intrinsic from %s",
1166178481Sjb				    ml->ml_size, tdesc_name(tdp));
1167178481Sjb				ml->ml_type = bitintrinsic(tdp, ml->ml_size);
1168178481Sjb			} else {
1169178481Sjb				debug(3, "using existing %d bit %s intrinsic",
1170178481Sjb				    ml->ml_size, tdesc_name(tdp));
1171178481Sjb				ml->ml_type = tdp;
1172178481Sjb			}
1173178481Sjb			return (1);
1174178481Sjb
1175178481Sjb		case POINTER:
1176178481Sjb		case TYPEDEF:
1177178481Sjb		case VOLATILE:
1178178481Sjb		case CONST:
1179178481Sjb		case RESTRICT:
1180178481Sjb			tdp = tdp->t_tdesc;
1181178481Sjb			break;
1182178481Sjb
1183178481Sjb		default:
1184178481Sjb			return (1);
1185178481Sjb		}
1186178481Sjb	}
1187178481Sjb
1188178481Sjb	terminate("type chain for bitfield member %s has a NULL", ml->ml_name);
1189178481Sjb	/*NOTREACHED*/
1190178481Sjb	return (0);
1191178481Sjb}
1192178481Sjb
1193178481Sjbvoid
1194178481Sjbresolve_typed_bitfields(void)
1195178481Sjb{
1196178481Sjb	(void) list_iter(typedbitfldmems,
1197178481Sjb	    resolve_typed_bitfields_cb, NULL);
1198178481Sjb}
1199