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