xref: /illumos-gate/usr/src/tools/stabs/stabs.c (revision f896265f)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1996-2002 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <limits.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 
31 #include "stabs.h"
32 
33 static struct tdesc *hash_table[BUCKETS];
34 static struct tdesc *name_table[BUCKETS];
35 
36 static void reset(void);
37 static jmp_buf	resetbuf;
38 
39 static char *get_line(void);
40 static void parseline(char *cp);
41 static char *soudef(char *cp, enum type type, struct tdesc **rtdp);
42 static void enumdef(char *cp, struct tdesc **rtdp);
43 static int compute_sum(char *w);
44 static struct tdesc *lookup(int h);
45 
46 static char *number(char *cp, int *n);
47 static char *name(char *cp, char **w);
48 static char *id(char *cp, int *h);
49 static char *offsize(char *cp, struct mlist *mlp);
50 static char *whitesp(char *cp);
51 static void addhash(struct tdesc *tdp, int num);
52 static void tagadd(char *w, int h, struct tdesc *tdp);
53 static void tagdecl(char *cp, struct tdesc **rtdp, int h, char *w);
54 static char *tdefdecl(char *cp, int h, struct tdesc **rtdp);
55 static char *intrinsic(char *cp, struct tdesc **rtdp);
56 static char *arraydef(char *cp, struct tdesc **rtdp);
57 
58 static int line_number = 0;
59 static int debug_line  = 0;
60 static char linebuf[MAXLINE];
61 
62 extern int debug_level;
63 
64 static void
debug(int level,char * cp,char * fmt,...)65 debug(int level, char *cp, char *fmt, ...)
66 {
67 	va_list ap;
68 	char buf[1024];
69 	char tmp[32];
70 	int i;
71 
72 	if (level > debug_level)
73 		return;
74 
75 	if (cp != NULL) {
76 		for (i = 0; i < 30; i++) {
77 			if (cp[i] == '\0')
78 				break;
79 			if (!iscntrl(cp[i]))
80 				tmp[i] = cp[i];
81 		}
82 		tmp[i] = '\0';
83 		(void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp);
84 	} else {
85 		(void) snprintf(buf, sizeof (buf), "%s\n", fmt);
86 	}
87 
88 	va_start(ap, fmt);
89 	(void) vfprintf(stderr, buf, ap);
90 	va_end(ap);
91 }
92 
93 
94 /* Report unexpected syntax in stabs. */
95 static void
expected(char * who,char * what,char * where)96 expected(
97 	char *who,	/* what function, or part thereof, is reporting */
98 	char *what,	/* what was expected */
99 	char *where)	/* where we were in the line of input */
100 {
101 	fprintf(stderr, "%s, input line %d: expecting \"%s\" at \"%s\"\n",
102 	    who, line_number, what, where);
103 	exit(1);
104 }
105 
106 /* Read a line from stdin into linebuf and increment line_number. */
107 static char *
get_line(void)108 get_line(void)
109 {
110 	char *cp = fgets(linebuf, MAXLINE, stdin);
111 	line_number++;
112 
113 	/* For debugging, you can set debug_line to a line to stop on. */
114 	if (line_number == debug_line) {
115 		fprintf(stderr, "Hit debug line number %d\n", line_number);
116 		for (;;)
117 			(void) sleep(1);
118 	}
119 	return (cp);
120 }
121 
122 /* Get the continuation of the current input line. */
123 static char *
get_continuation(void)124 get_continuation(void)
125 {
126 	char *cp = get_line();
127 	if (!cp) {
128 		fprintf(stderr, "expecting continuation line, "
129 		    "got end of input\n");
130 		exit(1);
131 	}
132 
133 	/* Skip to the quoted stuff. */
134 	while (*cp++ != '"')
135 		;
136 	return (cp);
137 }
138 
139 void
parse_input(void)140 parse_input(void)
141 {
142 	char *cp;
143 	int i = 0;
144 
145 	for (i = 0; i < BUCKETS; i++) {
146 		hash_table[i] = NULL;
147 		name_table[i] = NULL;
148 	}
149 
150 	/*
151 	 * get a line at a time from the .s stabs file and parse.
152 	 */
153 	while ((cp = get_line()) != NULL)
154 		parseline(cp);
155 }
156 
157 /*
158  * Parse each line of the .s file (stabs entry) gather meaningful information
159  * like name of type, size, offsets of fields etc.
160  */
161 static void
parseline(char * cp)162 parseline(char *cp)
163 {
164 	struct tdesc *tdp;
165 	char c, *w;
166 	int h, tagdef;
167 
168 	/*
169 	 * setup for reset()
170 	 */
171 	if (setjmp(resetbuf))
172 		return;
173 
174 	/*
175 	 * Look for lines of the form
176 	 *	.stabs	"str",n,n,n,n
177 	 * The part in '"' is then parsed.
178 	 */
179 	cp = whitesp(cp);
180 #define	STLEN	6
181 	debug(2, cp, "parseline");
182 	if (strncmp(cp, ".stabs", STLEN) != 0)
183 		reset();
184 	cp += STLEN;
185 #undef STLEN
186 	cp = whitesp(cp);
187 	if (*cp++ != '"')
188 		reset();
189 
190 	/*
191 	 * name:type		variable (ignored)
192 	 * name:ttype		typedef
193 	 * name:Ttype		struct tag define
194 	 */
195 	cp = whitesp(cp);
196 	cp = name(cp, &w);
197 
198 	tagdef = 0;
199 	switch (c = *cp++) {
200 	case 't': /* type */
201 		break;
202 	case 'T': /* struct, union, enum */
203 		tagdef = 1;
204 		break;
205 	default:
206 		reset();
207 	}
208 
209 	/*
210 	 * The type id and definition follow.
211 	 */
212 	cp = id(cp, &h);
213 	if (*cp == '"') {
214 		struct tdesc *ntdp;
215 
216 		cp++;
217 		ntdp = lookup(h);
218 		if (ntdp == NULL) {  /* if that type isn't defined yet */
219 			if (*cp++ != '=')  /* better be defining it now */
220 				expected("parseline/'0-9'", "=", cp - 1);
221 			cp = tdefdecl(cp, h, &tdp);
222 			addhash(tdp, h); /* for *(x,y) types */
223 		} else { /* that type is already defined */
224 			tdp = malloc(sizeof (*tdp));
225 			tdp->type = TYPEOF;
226 			tdp->name = (w != NULL) ? strdup(w) : NULL;
227 			tdp->data.tdesc = ntdp;
228 			addhash(tdp, h); /* for *(x,y) types */
229 			debug(3, NULL, "    %s defined as %s(%d)", w,
230 			    (ntdp->name != NULL) ? ntdp->name : "anon", h);
231 		}
232 		return;
233 	} else if (*cp++ != '=') {
234 		expected("parseline", "=", cp - 1);
235 	}
236 	if (tagdef) {
237 		tagdecl(cp, &tdp, h, w);
238 	} else {
239 		(void) tdefdecl(cp, h, &tdp);
240 		tagadd(w, h, tdp);
241 	}
242 }
243 
244 /*
245  * Check if we have this node in the hash table already
246  */
247 static struct tdesc *
lookup(int h)248 lookup(int h)
249 {
250 	int hash = HASH(h);
251 	struct tdesc *tdp = hash_table[hash];
252 
253 	while (tdp != NULL) {
254 		if (tdp->id == h)
255 			return (tdp);
256 		tdp = tdp->hash;
257 	}
258 	return (NULL);
259 }
260 
261 static char *
whitesp(char * cp)262 whitesp(char *cp)
263 {
264 	char c;
265 
266 	for (c = *cp++; isspace(c); c = *cp++)
267 		;
268 	--cp;
269 	return (cp);
270 }
271 
272 static char *
name(char * cp,char ** w)273 name(char *cp, char **w)
274 {
275 	char *new, *orig, c;
276 	int len;
277 
278 	orig = cp;
279 	c = *cp++;
280 	if (c == ':')
281 		*w = NULL;
282 	else if (isalpha(c) || c == '_') {
283 		for (c = *cp++; isalnum(c) || c == ' ' || c == '_'; c = *cp++)
284 			;
285 		if (c != ':')
286 			reset();
287 		len = cp - orig;
288 		new = malloc(len);
289 		while (orig < cp - 1)
290 			*new++ = *orig++;
291 		*new = '\0';
292 		*w = new - (len - 1);
293 	} else
294 		reset();
295 
296 	return (cp);
297 }
298 
299 static char *
number(char * cp,int * n)300 number(char *cp, int *n)
301 {
302 	char *next;
303 
304 	*n = (int)strtol(cp, &next, 10);
305 	if (next == cp)
306 		expected("number", "<number>", cp);
307 	return (next);
308 }
309 
310 static char *
id(char * cp,int * h)311 id(char *cp, int *h)
312 {
313 	int n1, n2;
314 
315 	if (*cp == '(') {	/* SunPro style */
316 		cp++;
317 		cp = number(cp, &n1);
318 		if (*cp++ != ',')
319 			expected("id", ",", cp - 1);
320 		cp = number(cp, &n2);
321 		if (*cp++ != ')')
322 			expected("id", ")", cp - 1);
323 		*h = n1 * 1000 + n2;
324 	} else if (isdigit(*cp)) { /* gcc style */
325 		cp = number(cp, &n1);
326 		*h = n1;
327 	} else {
328 		expected("id", "(/0-9", cp);
329 	}
330 	return (cp);
331 }
332 
333 static void
tagadd(char * w,int h,struct tdesc * tdp)334 tagadd(char *w, int h, struct tdesc *tdp)
335 {
336 	struct tdesc *otdp;
337 
338 	tdp->name = w;
339 	if (!(otdp = lookup(h)))
340 		addhash(tdp, h);
341 	else if (otdp != tdp) {
342 		fprintf(stderr, "duplicate entry\n");
343 		fprintf(stderr, "old: %s %d %d %d\n",
344 		    otdp->name ? otdp->name : "NULL",
345 		    otdp->type, otdp->id / 1000, otdp->id % 1000);
346 		fprintf(stderr, "new: %s %d %d %d\n",
347 		    tdp->name ? tdp->name : "NULL",
348 		    tdp->type, tdp->id / 1000, tdp->id % 1000);
349 	}
350 }
351 
352 static void
tagdecl(char * cp,struct tdesc ** rtdp,int h,char * w)353 tagdecl(char *cp, struct tdesc **rtdp, int h, char *w)
354 {
355 	debug(1, NULL, "tagdecl: declaring '%s'", w ? w : "(anon)");
356 	if ((*rtdp = lookup(h)) != NULL) {
357 		if (w != NULL) {
358 			if ((*rtdp)->name != NULL &&
359 			    strcmp((*rtdp)->name, w) != 0) {
360 				struct tdesc *tdp;
361 
362 				tdp = malloc(sizeof (*tdp));
363 				tdp->name = strdup(w);
364 				tdp->type = TYPEOF;
365 				tdp->data.tdesc = *rtdp;
366 				addhash(tdp, h); /* for *(x,y) types */
367 				debug(3, NULL, "    %s defined as %s(%d)", w,
368 				    ((*rtdp)->name != NULL) ?
369 				    (*rtdp)->name : "anon", h);
370 			} else if ((*rtdp)->name == NULL) {
371 				(*rtdp)->name = w;
372 				addhash(*rtdp, h);
373 			}
374 		}
375 	} else {
376 		*rtdp = malloc(sizeof (**rtdp));
377 		(*rtdp)->name = w;
378 		addhash(*rtdp, h);
379 	}
380 
381 	switch (*cp++) {
382 	case 's':
383 		(void) soudef(cp, STRUCT, rtdp);
384 		break;
385 	case 'u':
386 		(void) soudef(cp, UNION, rtdp);
387 		break;
388 	case 'e':
389 		enumdef(cp, rtdp);
390 		break;
391 	default:
392 		expected("tagdecl", "<tag type s/u/e>", cp - 1);
393 		break;
394 	}
395 }
396 
397 static char *
tdefdecl(char * cp,int h,struct tdesc ** rtdp)398 tdefdecl(char *cp, int h, struct tdesc **rtdp)
399 {
400 	struct tdesc *ntdp;
401 	char *w;
402 	int c, h2;
403 	char type;
404 
405 	debug(3, cp, "tdefdecl h=%d", h);
406 
407 	/* Type codes */
408 	switch (type = *cp) {
409 	case 'b': /* integer */
410 		c = *++cp;
411 		if (c != 's' && c != 'u')
412 			expected("tdefdecl/b", "[su]", cp - 1);
413 		c = *++cp;
414 		if (c == 'c')
415 			cp++;
416 		cp = intrinsic(cp, rtdp);
417 		break;
418 	case 'R': /* fp */
419 		/* skip up to and past ';' */
420 		while (*cp++ != ';')
421 			/* NULL */;
422 		cp = intrinsic(cp, rtdp);
423 		break;
424 	case '(': /* equiv to another type */
425 		cp = id(cp, &h2);
426 		ntdp = lookup(h2);
427 		if (ntdp == NULL) {  /* if that type isn't defined yet */
428 			if (*cp++ != '=')  /* better be defining it now */
429 				expected("tdefdecl/'('", "=", cp - 1);
430 			cp = tdefdecl(cp, h2, rtdp);
431 			ntdp = malloc(sizeof (*ntdp));
432 			ntdp->type = TYPEOF;
433 			ntdp->data.tdesc = *rtdp;
434 			addhash(ntdp, h2);
435 		} else { /* that type is already defined */
436 			*rtdp = malloc(sizeof (**rtdp));
437 			(*rtdp)->type = TYPEOF;
438 			(*rtdp)->data.tdesc = ntdp;
439 		}
440 		break;
441 	case '*':
442 		ntdp = NULL;
443 		cp = tdefdecl(cp + 1, h, &ntdp);
444 		if (ntdp == NULL)
445 			expected("tdefdecl/*", "id", cp);
446 
447 		*rtdp = malloc(sizeof (**rtdp));
448 		(*rtdp)->type = POINTER;
449 		(*rtdp)->size = model->pointersize;
450 		(*rtdp)->name = "pointer";
451 		(*rtdp)->data.tdesc = ntdp;
452 		break;
453 	case 'f':
454 		cp = tdefdecl(cp + 1, h, &ntdp);
455 		*rtdp = malloc(sizeof (**rtdp));
456 		(*rtdp)->type = FUNCTION;
457 		(*rtdp)->size = model->pointersize;
458 		(*rtdp)->name = "function";
459 		(*rtdp)->data.tdesc = ntdp;
460 		break;
461 	case 'a':
462 		cp++;
463 		if (*cp++ != 'r')
464 			expected("tdefdecl/a", "r", cp - 1);
465 		*rtdp = malloc(sizeof (**rtdp));
466 		(*rtdp)->type = ARRAY;
467 		(*rtdp)->name = "array";
468 		cp = arraydef(cp, rtdp);
469 		break;
470 	case 'x':
471 		c = *++cp;
472 		if (c != 's' && c != 'u' && c != 'e')
473 			expected("tdefdecl/x", "[sue]", cp - 1);
474 		cp = name(cp + 1, &w);
475 		*rtdp = malloc(sizeof (**rtdp));
476 		(*rtdp)->type = FORWARD;
477 		(*rtdp)->name = w;
478 		break;
479 	case 'B': /* volatile */
480 		cp = tdefdecl(cp + 1, h, &ntdp);
481 		*rtdp = malloc(sizeof (**rtdp));
482 		(*rtdp)->type = VOLATILE;
483 		(*rtdp)->size = 0;
484 		(*rtdp)->name = "volatile";
485 		(*rtdp)->data.tdesc = ntdp;
486 		break;
487 	case 'k': /* const */
488 		cp = tdefdecl(cp + 1, h, &ntdp);
489 		*rtdp = malloc(sizeof (**rtdp));
490 		(*rtdp)->type = CONST;
491 		(*rtdp)->size = 0;
492 		(*rtdp)->name = "const";
493 		(*rtdp)->data.tdesc = ntdp;
494 		break;
495 	case '0': case '1': case '2': case '3':	case '4':
496 	case '5': case '6': case '7': case '8': case '9':
497 		/* gcc equiv to another type */
498 		cp = id(cp, &h2);
499 		ntdp = lookup(h2);
500 		if (ntdp == NULL) {  /* if that type isn't defined yet */
501 			/* better be defining it now */
502 			if (*cp++ != '=') {
503 				if (h != h2)
504 					expected("tdefdecl/'0-9'", "=", cp - 1);
505 				/* defined in terms of itself */
506 				*rtdp = malloc(sizeof (**rtdp));
507 				(*rtdp)->type = INTRINSIC;
508 				(*rtdp)->name = "void";
509 				(*rtdp)->size = 0;
510 			} else {
511 				cp = tdefdecl(cp, h2, rtdp);
512 				ntdp = malloc(sizeof (*ntdp));
513 				ntdp->type = TYPEOF;
514 				ntdp->data.tdesc = *rtdp;
515 				addhash(ntdp, h2);
516 			}
517 		} else { /* that type is already defined */
518 			*rtdp = malloc(sizeof (**rtdp));
519 			(*rtdp)->type = TYPEOF;
520 			(*rtdp)->data.tdesc = ntdp;
521 		}
522 		break;
523 	case 'u':
524 	case 's':
525 		cp++;
526 
527 		*rtdp = malloc(sizeof (**rtdp));
528 		(*rtdp)->name = NULL;
529 		cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp);
530 		break;
531 	default:
532 		expected("tdefdecl", "<type code>", cp);
533 	}
534 	return (cp);
535 }
536 
537 static char *
intrinsic(char * cp,struct tdesc ** rtdp)538 intrinsic(char *cp, struct tdesc **rtdp)
539 {
540 	struct tdesc *tdp;
541 	int size;
542 
543 	cp = number(cp, &size);
544 	tdp = malloc(sizeof (*tdp));
545 	tdp->type = INTRINSIC;
546 	tdp->size = size;
547 	tdp->name = NULL;
548 	debug(3, NULL, "intrinsic: size=%ld", size);
549 	*rtdp = tdp;
550 	return (cp);
551 }
552 
553 static char *
soudef(char * cp,enum type type,struct tdesc ** rtdp)554 soudef(char *cp, enum type type, struct tdesc **rtdp)
555 {
556 	struct mlist **next_pp, *prev_p = NULL;
557 	char *w;
558 	int size;
559 	struct tdesc *tdp;
560 
561 	cp = number(cp, &size);
562 	(*rtdp)->size = size;
563 	(*rtdp)->type = type; /* s or u */
564 
565 	/*
566 	 * An '@' here indicates a bitmask follows.   This is so the
567 	 * compiler can pass information to debuggers about how structures
568 	 * are passed in the v9 world.  We don't need this information
569 	 * so we skip over it.
570 	 */
571 	if (cp[0] == '@')
572 		cp += 3;
573 
574 	debug(3, cp, "soudef: %s size=%d",
575 	    (*rtdp)->name ? (*rtdp)->name : "(anonsou)",
576 	    (*rtdp)->size);
577 
578 	next_pp = &((*rtdp)->data.members.forw); /* head for forward linklist */
579 	/* fill up the fields */
580 	while ((*cp != '"') && (*cp != ';')) { /* signifies end of fields */
581 		int h;
582 		struct mlist *mlp = malloc(sizeof (*mlp));
583 
584 		mlp->prev = prev_p;	/* links for the backward list */
585 		prev_p = mlp;
586 		*next_pp = mlp;		/* links for the forward list */
587 		next_pp = &mlp->next;
588 
589 		cp = name(cp, &w);
590 		mlp->name = w;
591 		cp = id(cp, &h);
592 		/*
593 		 * find the tdesc struct in the hash table for this type
594 		 * and stick a ptr in here
595 		 */
596 		tdp = lookup(h);
597 		if (tdp == NULL) { /* not in hash list */
598 			debug(3, NULL, "      defines %s (%d)", w, h);
599 			if (*cp++ != '=')
600 				expected("soudef", "=", cp - 1);
601 			cp = tdefdecl(cp, h, &tdp);
602 			addhash(tdp, h);
603 			debug(4, cp, "     soudef now looking at    ");
604 			cp++;
605 
606 		} else {
607 			debug(3, NULL, "      refers to %s (%d, %s)",
608 			    w ? w : "anon", h, tdp->name ? tdp->name : "anon");
609 		}
610 
611 		mlp->fdesc = tdp;
612 		cp = offsize(cp, mlp);	/* cp is now pointing to next field */
613 		if (*cp == '\\')	/* could be a continuation */
614 			cp = get_continuation();
615 	}
616 	(*rtdp)->data.members.back = prev_p;	/* head for backward linklist */
617 	return (cp);
618 }
619 
620 static char *
offsize(char * cp,struct mlist * mlp)621 offsize(char *cp, struct mlist *mlp)
622 {
623 	int offset, size;
624 
625 	if (*cp == ',')
626 		cp++;
627 	cp = number(cp, &offset);
628 	if (*cp++ != ',')
629 		expected("offsize/2", ",", cp - 1);
630 	cp = number(cp, &size);
631 	if (*cp++ != ';')
632 		expected("offsize/3", ";", cp - 1);
633 	mlp->offset = offset;
634 	mlp->size = size;
635 	return (cp);
636 }
637 
638 static char *
arraydef(char * cp,struct tdesc ** rtdp)639 arraydef(char *cp, struct tdesc **rtdp)
640 {
641 	int h;
642 	int start, end;
643 
644 	cp = id(cp, &h);
645 	if (*cp++ != ';')
646 		expected("arraydef/1", ";", cp - 1);
647 
648 	(*rtdp)->data.ardef = malloc(sizeof (struct ardef));
649 	(*rtdp)->data.ardef->indices = malloc(sizeof (struct element));
650 	(*rtdp)->data.ardef->indices->index_type = lookup(h);
651 
652 	cp = number(cp, &start); /* lower */
653 	if (*cp++ != ';')
654 		expected("arraydef/2", ";", cp - 1);
655 	cp = number(cp, &end);	/* upper */
656 	if (*cp++ != ';')
657 		expected("arraydef/3", ";", cp - 1);
658 	(*rtdp)->data.ardef->indices->range_start = start;
659 	(*rtdp)->data.ardef->indices->range_end = end;
660 #if 0
661 	if (isdigit(*cp)) {
662 		cp = number(cp, &contents_type); /* lower */
663 		tdp = lookup(contents_type);
664 		if (tdp != NULL) {
665 			(*rtdp)->data.ardef->contents = tdp;
666 		} else {
667 			if (*cp != '=')
668 				expected("arraydef/4", "=", cp);
669 			cp = tdefdecl(cp + 1, h, &tdp);
670 			addhash(tdp, h); /* for *(x,y) types */
671 			(*rtdp)->data.ardef->contents = tdp;
672 		}
673 	} /* else  */
674 #endif
675 	cp = tdefdecl(cp, h, &((*rtdp)->data.ardef->contents));
676 	return (cp);
677 }
678 
679 static void
enumdef(char * cp,struct tdesc ** rtdp)680 enumdef(char *cp, struct tdesc **rtdp)
681 {
682 	struct elist *elp, **prev;
683 	char *w;
684 
685 	(*rtdp)->type = ENUM;
686 	(*rtdp)->data.emem = NULL;
687 
688 	prev = &((*rtdp)->data.emem);
689 	while (*cp != ';') {
690 		elp = malloc(sizeof (*elp));
691 		elp->next = NULL;
692 		*prev = elp;
693 		cp = name(cp, &w);
694 		elp->name = w;
695 		cp = number(cp, &elp->number);
696 		debug(3, NULL, "enum %s: %s=%ld",
697 		    (*rtdp)->name ? (*rtdp)->name : "(anon enum)",
698 		    elp->name, elp->number);
699 		prev = &elp->next;
700 		if (*cp++ != ',')
701 			expected("enumdef", ",", cp - 1);
702 		if (*cp == '\\')
703 			cp = get_continuation();
704 	}
705 }
706 
707 /*
708  * Add a node to the hash queues.
709  */
710 static void
addhash(struct tdesc * tdp,int num)711 addhash(struct tdesc *tdp, int num)
712 {
713 	int hash = HASH(num);
714 	struct tdesc *ttdp;
715 	char added_num = 0, added_name = 0;
716 
717 	/*
718 	 * If it already exists in the hash table don't add it again
719 	 * (but still check to see if the name should be hashed).
720 	 */
721 	ttdp = lookup(num);
722 	if (ttdp == NULL) {
723 		tdp->id = num;
724 		tdp->hash = hash_table[hash];
725 		hash_table[hash] = tdp;
726 		added_num = 1;
727 	}
728 
729 	if (tdp->name != NULL) {
730 		ttdp = lookupname(tdp->name);
731 		if (ttdp == NULL) {
732 			hash = compute_sum(tdp->name);
733 			tdp->next = name_table[hash];
734 			name_table[hash] = tdp;
735 			added_name = 1;
736 		}
737 	}
738 	if (!added_num && !added_name) {
739 		fprintf(stderr, "stabs: broken hash\n");
740 		exit(1);
741 	}
742 }
743 
744 struct tdesc *
lookupname(char * name)745 lookupname(char *name)
746 {
747 	int hash = compute_sum(name);
748 	struct tdesc *tdp, *ttdp = NULL;
749 
750 	for (tdp = name_table[hash]; tdp != NULL; tdp = tdp->next) {
751 		if (tdp->name != NULL && strcmp(tdp->name, name) == 0) {
752 			if (tdp->type == STRUCT || tdp->type == UNION ||
753 			    tdp->type == ENUM || tdp->type == INTRINSIC)
754 				return (tdp);
755 			if (tdp->type == TYPEOF)
756 				ttdp = tdp;
757 		}
758 	}
759 	return (ttdp);
760 }
761 
762 static int
compute_sum(char * w)763 compute_sum(char *w)
764 {
765 	char c;
766 	int sum;
767 
768 	for (sum = 0; (c = *w) != '\0'; sum += c, w++)
769 		;
770 	return (HASH(sum));
771 }
772 
773 static void
reset(void)774 reset(void)
775 {
776 	longjmp(resetbuf, 1);
777 	/* NOTREACHED */
778 }
779