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