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