]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - cddl/contrib/opensolaris/tools/ctf/cvt/st_parse.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / cddl / contrib / opensolaris / tools / ctf / cvt / st_parse.c
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
55 static int faketypenumber = 100000000;
56
57 static tdesc_t *hash_table[BUCKETS];
58 static tdesc_t *name_table[BUCKETS];
59
60 list_t *typedbitfldmems;
61
62 static void reset(void);
63 static jmp_buf  resetbuf;
64
65 static char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp);
66 static void enumdef(char *cp, tdesc_t **rtdp);
67 static int compute_sum(const char *w);
68
69 static char *number(char *cp, int *n);
70 static char *name(char *cp, char **w);
71 static char *id(char *cp, int *h);
72 static char *whitesp(char *cp);
73 static void addhash(tdesc_t *tdp, int num);
74 static int tagadd(char *w, int h, tdesc_t *tdp);
75 static char *tdefdecl(char *cp, int h, tdesc_t **rtdp);
76 static char *intrinsic(char *cp, tdesc_t **rtdp);
77 static char *arraydef(char *cp, tdesc_t **rtdp);
78
79 int debug_parse = DEBUG_PARSE;
80
81 /*PRINTFLIKE3*/
82 static void
83 parse_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. */
113 static 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*/
127 void
128 parse_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
143 void
144 parse_finish(tdata_t *td)
145 {
146         td->td_nextid = ++faketypenumber;
147 }
148
149 static tdesc_t *
150 unres_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
161 static char *
162 read_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
189 static iitype_t
190 parse_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
248 static iitype_t
249 parse_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
288 static iitype_t
289 parse_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
345 static iitype_t
346 parse_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
404 int
405 parse_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  */
465 tdesc_t *
466 lookup(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
479 static char *
480 whitesp(char *cp)
481 {
482         char c;
483
484         for (c = *cp++; isspace(c); c = *cp++);
485         --cp;
486         return (cp);
487 }
488
489 static char *
490 name(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
516 static char *
517 number(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
527 static char *
528 id(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
550 static int
551 tagadd(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
570 static char *
571 tdefdecl(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
774 static char *
775 intrinsic(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
834 static tdesc_t *
835 bitintrinsic(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
850 static char *
851 offsize(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
868 static tdesc_t *
869 find_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
886 static char *
887 soudef(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
976 static char *
977 arraydef(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
1015 static void
1016 enumdef(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
1040 static tdesc_t *
1041 lookup_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
1058 tdesc_t *
1059 lookupname(const char *name1)
1060 {
1061         return (lookup_name(name_table, name1));
1062 }
1063
1064 /*
1065  * Add a node to the hash queues.
1066  */
1067 static void
1068 addhash(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
1101 static int
1102 compute_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
1112 static void
1113 reset(void)
1114 {
1115         longjmp(resetbuf, 1);
1116 }
1117
1118 void
1119 check_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*/
1152 static int
1153 resolve_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
1193 void
1194 resolve_typed_bitfields(void)
1195 {
1196         (void) list_iter(typedbitfldmems,
1197             resolve_typed_bitfields_cb, NULL);
1198 }