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