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