st_parse.c revision 178481
1178481Sjb/* 2178481Sjb * CDDL HEADER START 3178481Sjb * 4178481Sjb * The contents of this file are subject to the terms of the 5178481Sjb * Common Development and Distribution License (the "License"). 6178481Sjb * You may not use this file except in compliance with the License. 7178481Sjb * 8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178481Sjb * or http://www.opensolaris.org/os/licensing. 10178481Sjb * See the License for the specific language governing permissions 11178481Sjb * and limitations under the License. 12178481Sjb * 13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178481Sjb * If applicable, add the following below this CDDL HEADER, with the 16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178481Sjb * 19178481Sjb * CDDL HEADER END 20178481Sjb */ 21178481Sjb/* 22178481Sjb * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23178481Sjb * Use is subject to license terms. 24178481Sjb */ 25178481Sjb 26178481Sjb#pragma ident "%Z%%M% %I% %E% SMI" 27178481Sjb 28178481Sjb/* 29178481Sjb * This file is a sewer. 30178481Sjb */ 31178481Sjb 32178481Sjb#include <limits.h> 33178481Sjb#include <stdarg.h> 34178481Sjb#include <stdio.h> 35178481Sjb#include <assert.h> 36178481Sjb#include <strings.h> 37178481Sjb#include <setjmp.h> 38178481Sjb#include <ctype.h> 39178481Sjb#include <uts/common/sys/ctf.h> 40178481Sjb 41178481Sjb#include "ctftools.h" 42178481Sjb#include "memory.h" 43178481Sjb#include "list.h" 44178481Sjb 45178481Sjb#define HASH(NUM) ((int)(NUM & (BUCKETS - 1))) 46178481Sjb#define BUCKETS 128 47178481Sjb 48178481Sjb#define TYPEPAIRMULT 10000 49178481Sjb#define MAKETYPEID(file, num) ((file) * TYPEPAIRMULT + num) 50178481Sjb#define TYPEFILE(tid) ((tid) / TYPEPAIRMULT) 51178481Sjb#define TYPENUM(tid) ((tid) % TYPEPAIRMULT) 52178481Sjb 53178481Sjb#define expected(a, b, c) _expected(a, b, c, __LINE__) 54178481Sjb 55178481Sjbstatic int faketypenumber = 100000000; 56178481Sjb 57178481Sjbstatic tdesc_t *hash_table[BUCKETS]; 58178481Sjbstatic tdesc_t *name_table[BUCKETS]; 59178481Sjb 60178481Sjblist_t *typedbitfldmems; 61178481Sjb 62178481Sjbstatic void reset(void); 63178481Sjbstatic jmp_buf resetbuf; 64178481Sjb 65178481Sjbstatic char *soudef(char *cp, stabtype_t type, tdesc_t **rtdp); 66178481Sjbstatic void enumdef(char *cp, tdesc_t **rtdp); 67178481Sjbstatic int compute_sum(const char *w); 68178481Sjb 69178481Sjbstatic char *number(char *cp, int *n); 70178481Sjbstatic char *name(char *cp, char **w); 71178481Sjbstatic char *id(char *cp, int *h); 72178481Sjbstatic char *whitesp(char *cp); 73178481Sjbstatic void addhash(tdesc_t *tdp, int num); 74178481Sjbstatic int tagadd(char *w, int h, tdesc_t *tdp); 75178481Sjbstatic char *tdefdecl(char *cp, int h, tdesc_t **rtdp); 76178481Sjbstatic char *intrinsic(char *cp, tdesc_t **rtdp); 77178481Sjbstatic char *arraydef(char *cp, tdesc_t **rtdp); 78178481Sjb 79178481Sjbint debug_parse = DEBUG_PARSE; 80178481Sjb 81178481Sjb/*PRINTFLIKE3*/ 82178481Sjbstatic void 83178481Sjbparse_debug(int level, char *cp, const char *fmt, ...) 84178481Sjb{ 85178481Sjb va_list ap; 86178481Sjb char buf[1024]; 87178481Sjb char tmp[32]; 88178481Sjb int i; 89178481Sjb 90178481Sjb if (level > debug_level || !debug_parse) 91178481Sjb return; 92178481Sjb 93178481Sjb if (cp != NULL) { 94178481Sjb for (i = 0; i < 30; i++) { 95178481Sjb if (cp[i] == '\0') 96178481Sjb break; 97178481Sjb if (!iscntrl(cp[i])) 98178481Sjb tmp[i] = cp[i]; 99178481Sjb } 100178481Sjb tmp[i] = '\0'; 101178481Sjb (void) snprintf(buf, sizeof (buf), "%s [cp='%s']\n", fmt, tmp); 102178481Sjb } else { 103178481Sjb strcpy(buf, fmt); 104178481Sjb strcat(buf, "\n"); 105178481Sjb } 106178481Sjb 107178481Sjb va_start(ap, fmt); 108178481Sjb vadebug(level, buf, ap); 109178481Sjb va_end(ap); 110178481Sjb} 111178481Sjb 112178481Sjb/* Report unexpected syntax in stabs. */ 113178481Sjbstatic void 114178481Sjb_expected( 115178481Sjb const char *who, /* what function, or part thereof, is reporting */ 116178481Sjb const char *what, /* what was expected */ 117178481Sjb const char *where, /* where we were in the line of input */ 118178481Sjb int line) 119178481Sjb{ 120178481Sjb fprintf(stderr, "%s, expecting \"%s\" at \"%s\"\n", who, what, where); 121178481Sjb fprintf(stderr, "code line: %d, file %s\n", line, 122178481Sjb (curhdr ? curhdr : "NO FILE")); 123178481Sjb reset(); 124178481Sjb} 125178481Sjb 126178481Sjb/*ARGSUSED*/ 127178481Sjbvoid 128178481Sjbparse_init(tdata_t *td __unused) 129178481Sjb{ 130178481Sjb int i; 131178481Sjb 132178481Sjb for (i = 0; i < BUCKETS; i++) { 133178481Sjb hash_table[i] = NULL; 134178481Sjb name_table[i] = NULL; 135178481Sjb } 136178481Sjb 137178481Sjb if (typedbitfldmems != NULL) { 138178481Sjb list_free(typedbitfldmems, NULL, NULL); 139178481Sjb typedbitfldmems = NULL; 140178481Sjb } 141178481Sjb} 142178481Sjb 143178481Sjbvoid 144178481Sjbparse_finish(tdata_t *td) 145178481Sjb{ 146178481Sjb td->td_nextid = ++faketypenumber; 147178481Sjb} 148178481Sjb 149178481Sjbstatic tdesc_t * 150178481Sjbunres_new(int tid) 151178481Sjb{ 152178481Sjb tdesc_t *tdp; 153178481Sjb 154178481Sjb tdp = xcalloc(sizeof (*tdp)); 155178481Sjb tdp->t_type = TYPEDEF_UNRES; 156178481Sjb tdp->t_id = tid; 157178481Sjb 158178481Sjb return (tdp); 159178481Sjb} 160178481Sjb 161178481Sjbstatic char * 162178481Sjbread_tid(char *cp, tdesc_t **tdpp) 163178481Sjb{ 164178481Sjb tdesc_t *tdp; 165178481Sjb int tid; 166178481Sjb 167178481Sjb cp = id(cp, &tid); 168178481Sjb 169178481Sjb assert(tid != 0); 170178481Sjb 171178481Sjb if (*cp == '=') { 172178481Sjb if (!(cp = tdefdecl(cp + 1, tid, &tdp))) 173178481Sjb return (NULL); 174178481Sjb if (tdp->t_id && tdp->t_id != tid) { 175178481Sjb tdesc_t *ntdp = xcalloc(sizeof (*ntdp)); 176178481Sjb 177178481Sjb ntdp->t_type = TYPEDEF; 178178481Sjb ntdp->t_tdesc = tdp; 179178481Sjb tdp = ntdp; 180178481Sjb } 181178481Sjb addhash(tdp, tid); 182178481Sjb } else if ((tdp = lookup(tid)) == NULL) 183178481Sjb tdp = unres_new(tid); 184178481Sjb 185178481Sjb *tdpp = tdp; 186178481Sjb return (cp); 187178481Sjb} 188178481Sjb 189178481Sjbstatic iitype_t 190178481Sjbparse_fun(char *cp, iidesc_t *ii) 191178481Sjb{ 192178481Sjb iitype_t iitype = 0; 193178481Sjb tdesc_t *tdp; 194178481Sjb tdesc_t **args = NULL; 195178481Sjb int nargs = 0; 196178481Sjb int va = 0; 197178481Sjb 198178481Sjb /* 199178481Sjb * name:P prototype 200178481Sjb * name:F global function 201178481Sjb * name:f static function 202178481Sjb */ 203178481Sjb switch (*cp++) { 204178481Sjb case 'P': 205178481Sjb iitype = II_NOT; /* not interesting */ 206178481Sjb break; 207178481Sjb 208178481Sjb case 'F': 209178481Sjb iitype = II_GFUN; 210178481Sjb break; 211178481Sjb 212178481Sjb case 'f': 213178481Sjb iitype = II_SFUN; 214178481Sjb break; 215178481Sjb 216178481Sjb default: 217178481Sjb expected("parse_nfun", "[PfF]", cp - 1); 218178481Sjb } 219178481Sjb 220178481Sjb if (!(cp = read_tid(cp, &tdp))) 221178481Sjb return (-1); 222178481Sjb 223178481Sjb if (*cp) 224178481Sjb args = xmalloc(sizeof (tdesc_t *) * FUNCARG_DEF); 225178481Sjb 226178481Sjb while (*cp && *++cp) { 227178481Sjb if (*cp == '0') { 228178481Sjb va = 1; 229178481Sjb continue; 230178481Sjb } 231178481Sjb 232178481Sjb nargs++; 233178481Sjb if (nargs > FUNCARG_DEF) 234178481Sjb args = xrealloc(args, sizeof (tdesc_t *) * nargs); 235178481Sjb if (!(cp = read_tid(cp, &args[nargs - 1]))) 236178481Sjb return (-1); 237178481Sjb } 238178481Sjb 239178481Sjb ii->ii_type = iitype; 240178481Sjb ii->ii_dtype = tdp; 241178481Sjb ii->ii_nargs = nargs; 242178481Sjb ii->ii_args = args; 243178481Sjb ii->ii_vargs = va; 244178481Sjb 245178481Sjb return (iitype); 246178481Sjb} 247178481Sjb 248178481Sjbstatic iitype_t 249178481Sjbparse_sym(char *cp, iidesc_t *ii) 250178481Sjb{ 251178481Sjb tdesc_t *tdp; 252178481Sjb iitype_t iitype = 0; 253178481Sjb 254178481Sjb /* 255178481Sjb * name:G global variable 256178481Sjb * name:S static variable 257178481Sjb */ 258178481Sjb switch (*cp++) { 259178481Sjb case 'G': 260178481Sjb iitype = II_GVAR; 261178481Sjb break; 262178481Sjb case 'S': 263178481Sjb iitype = II_SVAR; 264178481Sjb break; 265178481Sjb case 'p': 266178481Sjb iitype = II_PSYM; 267178481Sjb break; 268178481Sjb case '(': 269178481Sjb cp--; 270178481Sjb /*FALLTHROUGH*/ 271178481Sjb case 'r': 272178481Sjb case 'V': 273178481Sjb iitype = II_NOT; /* not interesting */ 274178481Sjb break; 275178481Sjb default: 276178481Sjb expected("parse_sym", "[GprSV(]", cp - 1); 277178481Sjb } 278178481Sjb 279178481Sjb if (!(cp = read_tid(cp, &tdp))) 280178481Sjb return (-1); 281178481Sjb 282178481Sjb ii->ii_type = iitype; 283178481Sjb ii->ii_dtype = tdp; 284178481Sjb 285178481Sjb return (iitype); 286178481Sjb} 287178481Sjb 288178481Sjbstatic iitype_t 289178481Sjbparse_type(char *cp, iidesc_t *ii) 290178481Sjb{ 291178481Sjb tdesc_t *tdp, *ntdp; 292178481Sjb int tid; 293178481Sjb 294178481Sjb if (*cp++ != 't') 295178481Sjb expected("parse_type", "t (type)", cp - 1); 296178481Sjb 297178481Sjb cp = id(cp, &tid); 298178481Sjb if ((tdp = lookup(tid)) == NULL) { 299178481Sjb if (*cp++ != '=') 300178481Sjb expected("parse_type", "= (definition)", cp - 1); 301178481Sjb 302178481Sjb (void) tdefdecl(cp, tid, &tdp); 303178481Sjb 304178481Sjb if (tdp->t_id == tid) { 305178481Sjb assert(tdp->t_type != TYPEDEF); 306178481Sjb assert(!lookup(tdp->t_id)); 307178481Sjb 308178481Sjb if (!streq(tdp->t_name, ii->ii_name)) { 309178481Sjb ntdp = xcalloc(sizeof (*ntdp)); 310178481Sjb ntdp->t_name = xstrdup(ii->ii_name); 311178481Sjb ntdp->t_type = TYPEDEF; 312178481Sjb ntdp->t_tdesc = tdp; 313178481Sjb tdp->t_id = faketypenumber++; 314178481Sjb tdp = ntdp; 315178481Sjb } 316178481Sjb } else if (tdp->t_id == 0) { 317178481Sjb assert(tdp->t_type == FORWARD || 318178481Sjb tdp->t_type == INTRINSIC); 319178481Sjb 320178481Sjb if (tdp->t_name && !streq(tdp->t_name, ii->ii_name)) { 321178481Sjb ntdp = xcalloc(sizeof (*ntdp)); 322178481Sjb ntdp->t_name = xstrdup(ii->ii_name); 323178481Sjb ntdp->t_type = TYPEDEF; 324178481Sjb ntdp->t_tdesc = tdp; 325178481Sjb tdp->t_id = faketypenumber++; 326178481Sjb tdp = ntdp; 327178481Sjb } 328178481Sjb } else if (tdp->t_id != tid) { 329178481Sjb ntdp = xcalloc(sizeof (*ntdp)); 330178481Sjb ntdp->t_name = xstrdup(ii->ii_name); 331178481Sjb ntdp->t_type = TYPEDEF; 332178481Sjb ntdp->t_tdesc = tdp; 333178481Sjb tdp = ntdp; 334178481Sjb } 335178481Sjb 336178481Sjb if (tagadd(ii->ii_name, tid, tdp) < 0) 337178481Sjb return (-1); 338178481Sjb } 339178481Sjb 340178481Sjb ii->ii_type = II_TYPE; 341178481Sjb ii->ii_dtype = tdp; 342178481Sjb return (II_TYPE); 343178481Sjb} 344178481Sjb 345178481Sjbstatic iitype_t 346178481Sjbparse_sou(char *cp, iidesc_t *idp) 347178481Sjb{ 348178481Sjb tdesc_t *rtdp; 349178481Sjb int tid; 350178481Sjb 351178481Sjb if (*cp++ != 'T') 352178481Sjb expected("parse_sou", "T (sou)", cp - 1); 353178481Sjb 354178481Sjb cp = id(cp, &tid); 355178481Sjb if (*cp++ != '=') 356178481Sjb expected("parse_sou", "= (definition)", cp - 1); 357178481Sjb 358178481Sjb parse_debug(1, NULL, "parse_sou: declaring '%s'", idp->ii_name ? 359178481Sjb idp->ii_name : "(anon)"); 360178481Sjb if ((rtdp = lookup(tid)) != NULL) { 361178481Sjb if (idp->ii_name != NULL) { 362178481Sjb if (rtdp->t_name != NULL && 363178481Sjb strcmp(rtdp->t_name, idp->ii_name) != 0) { 364178481Sjb tdesc_t *tdp; 365178481Sjb 366178481Sjb tdp = xcalloc(sizeof (*tdp)); 367178481Sjb tdp->t_name = xstrdup(idp->ii_name); 368178481Sjb tdp->t_type = TYPEDEF; 369178481Sjb tdp->t_tdesc = rtdp; 370178481Sjb addhash(tdp, tid); /* for *(x,y) types */ 371178481Sjb parse_debug(3, NULL, " %s defined as %s(%d)", 372178481Sjb idp->ii_name, tdesc_name(rtdp), tid); 373178481Sjb } else if (rtdp->t_name == NULL) { 374178481Sjb rtdp->t_name = xstrdup(idp->ii_name); 375178481Sjb addhash(rtdp, tid); 376178481Sjb } 377178481Sjb } 378178481Sjb } else { 379178481Sjb rtdp = xcalloc(sizeof (*rtdp)); 380178481Sjb rtdp->t_name = idp->ii_name ? xstrdup(idp->ii_name) : NULL; 381178481Sjb addhash(rtdp, tid); 382178481Sjb } 383178481Sjb 384178481Sjb switch (*cp++) { 385178481Sjb case 's': 386178481Sjb (void) soudef(cp, STRUCT, &rtdp); 387178481Sjb break; 388178481Sjb case 'u': 389178481Sjb (void) soudef(cp, UNION, &rtdp); 390178481Sjb break; 391178481Sjb case 'e': 392178481Sjb enumdef(cp, &rtdp); 393178481Sjb break; 394178481Sjb default: 395178481Sjb expected("parse_sou", "<tag type s/u/e>", cp - 1); 396178481Sjb break; 397178481Sjb } 398178481Sjb 399178481Sjb idp->ii_type = II_SOU; 400178481Sjb idp->ii_dtype = rtdp; 401178481Sjb return (II_SOU); 402178481Sjb} 403178481Sjb 404178481Sjbint 405178481Sjbparse_stab(stab_t *stab, char *cp, iidesc_t **iidescp) 406178481Sjb{ 407178481Sjb iidesc_t *ii = NULL; 408178481Sjb iitype_t (*parse)(char *, iidesc_t *); 409178481Sjb int rc; 410178481Sjb 411178481Sjb /* 412178481Sjb * set up for reset() 413178481Sjb */ 414178481Sjb if (setjmp(resetbuf)) 415178481Sjb return (-1); 416178481Sjb 417178481Sjb cp = whitesp(cp); 418178481Sjb ii = iidesc_new(NULL); 419178481Sjb cp = name(cp, &ii->ii_name); 420178481Sjb 421178481Sjb switch (stab->n_type) { 422178481Sjb case N_FUN: 423178481Sjb parse = parse_fun; 424178481Sjb break; 425178481Sjb 426178481Sjb case N_LSYM: 427178481Sjb if (*cp == 't') 428178481Sjb parse = parse_type; 429178481Sjb else if (*cp == 'T') 430178481Sjb parse = parse_sou; 431178481Sjb else 432178481Sjb parse = parse_sym; 433178481Sjb break; 434178481Sjb 435178481Sjb case N_GSYM: 436178481Sjb case N_LCSYM: 437178481Sjb case N_PSYM: 438178481Sjb case N_ROSYM: 439178481Sjb case N_RSYM: 440178481Sjb case N_STSYM: 441178481Sjb parse = parse_sym; 442178481Sjb break; 443178481Sjb default: 444178481Sjb parse_debug(1, cp, "Unknown stab type %#x", stab->n_type); 445178481Sjb bzero(&resetbuf, sizeof (resetbuf)); 446178481Sjb return (-1); 447178481Sjb } 448178481Sjb 449178481Sjb rc = parse(cp, ii); 450178481Sjb bzero(&resetbuf, sizeof (resetbuf)); 451178481Sjb 452178481Sjb if (rc < 0 || ii->ii_type == II_NOT) { 453178481Sjb iidesc_free(ii, NULL); 454178481Sjb return (rc); 455178481Sjb } 456178481Sjb 457178481Sjb *iidescp = ii; 458178481Sjb 459178481Sjb return (1); 460178481Sjb} 461178481Sjb 462178481Sjb/* 463178481Sjb * Check if we have this node in the hash table already 464178481Sjb */ 465178481Sjbtdesc_t * 466178481Sjblookup(int h) 467178481Sjb{ 468178481Sjb int bucket = HASH(h); 469178481Sjb tdesc_t *tdp = hash_table[bucket]; 470178481Sjb 471178481Sjb while (tdp != NULL) { 472178481Sjb if (tdp->t_id == h) 473178481Sjb return (tdp); 474178481Sjb tdp = tdp->t_hash; 475178481Sjb } 476178481Sjb return (NULL); 477178481Sjb} 478178481Sjb 479178481Sjbstatic char * 480178481Sjbwhitesp(char *cp) 481178481Sjb{ 482178481Sjb char c; 483178481Sjb 484178481Sjb for (c = *cp++; isspace(c); c = *cp++); 485178481Sjb --cp; 486178481Sjb return (cp); 487178481Sjb} 488178481Sjb 489178481Sjbstatic char * 490178481Sjbname(char *cp, char **w) 491178481Sjb{ 492178481Sjb char *new, *orig, c; 493178481Sjb int len; 494178481Sjb 495178481Sjb orig = cp; 496178481Sjb c = *cp++; 497178481Sjb if (c == ':') 498178481Sjb *w = NULL; 499178481Sjb else if (isalpha(c) || strchr("_.$", c)) { 500178481Sjb for (c = *cp++; isalnum(c) || strchr(" _.$", c); c = *cp++) 501178481Sjb ; 502178481Sjb if (c != ':') 503178481Sjb reset(); 504178481Sjb len = cp - orig; 505178481Sjb new = xmalloc(len); 506178481Sjb while (orig < cp - 1) 507178481Sjb *new++ = *orig++; 508178481Sjb *new = '\0'; 509178481Sjb *w = new - (len - 1); 510178481Sjb } else 511178481Sjb reset(); 512178481Sjb 513178481Sjb return (cp); 514178481Sjb} 515178481Sjb 516178481Sjbstatic char * 517178481Sjbnumber(char *cp, int *n) 518178481Sjb{ 519178481Sjb char *next; 520178481Sjb 521178481Sjb *n = (int)strtol(cp, &next, 10); 522178481Sjb if (next == cp) 523178481Sjb expected("number", "<number>", cp); 524178481Sjb return (next); 525178481Sjb} 526178481Sjb 527178481Sjbstatic char * 528178481Sjbid(char *cp, int *h) 529178481Sjb{ 530178481Sjb int n1, n2; 531178481Sjb 532178481Sjb if (*cp == '(') { /* SunPro style */ 533178481Sjb cp++; 534178481Sjb cp = number(cp, &n1); 535178481Sjb if (*cp++ != ',') 536178481Sjb expected("id", ",", cp - 1); 537178481Sjb cp = number(cp, &n2); 538178481Sjb if (*cp++ != ')') 539178481Sjb expected("id", ")", cp - 1); 540178481Sjb *h = MAKETYPEID(n1, n2); 541178481Sjb } else if (isdigit(*cp)) { /* gcc style */ 542178481Sjb cp = number(cp, &n1); 543178481Sjb *h = n1; 544178481Sjb } else { 545178481Sjb expected("id", "(/0-9", cp); 546178481Sjb } 547178481Sjb return (cp); 548178481Sjb} 549178481Sjb 550178481Sjbstatic int 551178481Sjbtagadd(char *w, int h, tdesc_t *tdp) 552178481Sjb{ 553178481Sjb tdesc_t *otdp; 554178481Sjb 555178481Sjb tdp->t_name = w; 556178481Sjb if (!(otdp = lookup(h))) 557178481Sjb addhash(tdp, h); 558178481Sjb else if (otdp != tdp) { 559178481Sjb warning("duplicate entry\n"); 560178481Sjb warning(" old: %s %d (%d,%d)\n", tdesc_name(otdp), 561178481Sjb otdp->t_type, TYPEFILE(otdp->t_id), TYPENUM(otdp->t_id)); 562178481Sjb warning(" new: %s %d (%d,%d)\n", tdesc_name(tdp), 563178481Sjb tdp->t_type, TYPEFILE(tdp->t_id), TYPENUM(tdp->t_id)); 564178481Sjb return (-1); 565178481Sjb } 566178481Sjb 567178481Sjb return (0); 568178481Sjb} 569178481Sjb 570178481Sjbstatic char * 571178481Sjbtdefdecl(char *cp, int h, tdesc_t **rtdp) 572178481Sjb{ 573178481Sjb tdesc_t *ntdp; 574178481Sjb char *w; 575178481Sjb int c, h2; 576178481Sjb char type; 577178481Sjb 578178481Sjb parse_debug(3, cp, "tdefdecl h=%d", h); 579178481Sjb 580178481Sjb /* Type codes */ 581178481Sjb switch (type = *cp) { 582178481Sjb case 'b': /* integer */ 583178481Sjb case 'R': /* fp */ 584178481Sjb cp = intrinsic(cp, rtdp); 585178481Sjb break; 586178481Sjb case '(': /* equiv to another type */ 587178481Sjb cp = id(cp, &h2); 588178481Sjb ntdp = lookup(h2); 589178481Sjb 590178481Sjb if (ntdp != NULL && *cp == '=') { 591178481Sjb if (ntdp->t_type == FORWARD && *(cp + 1) == 'x') { 592178481Sjb /* 593178481Sjb * The 6.2 compiler, and possibly others, will 594178481Sjb * sometimes emit the same stab for a forward 595178481Sjb * declaration twice. That is, "(1,2)=xsfoo:" 596178481Sjb * will sometimes show up in two different 597178481Sjb * places. This is, of course, quite fun. We 598178481Sjb * want CTF to work in spite of the compiler, 599178481Sjb * so we'll let this one through. 600178481Sjb */ 601178481Sjb char *c2 = cp + 2; 602178481Sjb char *nm; 603178481Sjb 604178481Sjb if (!strchr("sue", *c2++)) { 605178481Sjb expected("tdefdecl/x-redefine", "[sue]", 606178481Sjb c2 - 1); 607178481Sjb } 608178481Sjb 609178481Sjb c2 = name(c2, &nm); 610178481Sjb if (strcmp(nm, ntdp->t_name) != 0) { 611178481Sjb terminate("Stabs error: Attempt to " 612178481Sjb "redefine type (%d,%d) as " 613178481Sjb "something else: %s\n", 614178481Sjb TYPEFILE(h2), TYPENUM(h2), 615178481Sjb c2 - 1); 616178481Sjb } 617178481Sjb free(nm); 618178481Sjb 619178481Sjb h2 = faketypenumber++; 620178481Sjb ntdp = NULL; 621178481Sjb } else { 622178481Sjb terminate("Stabs error: Attempting to " 623178481Sjb "redefine type (%d,%d)\n", TYPEFILE(h2), 624178481Sjb TYPENUM(h2)); 625178481Sjb } 626178481Sjb } 627178481Sjb 628178481Sjb if (ntdp == NULL) { /* if that type isn't defined yet */ 629178481Sjb if (*cp != '=') { 630178481Sjb /* record it as unresolved */ 631178481Sjb parse_debug(3, NULL, "tdefdecl unres type %d", 632178481Sjb h2); 633178481Sjb *rtdp = calloc(sizeof (**rtdp), 1); 634178481Sjb (*rtdp)->t_type = TYPEDEF_UNRES; 635178481Sjb (*rtdp)->t_id = h2; 636178481Sjb break; 637178481Sjb } else 638178481Sjb cp++; 639178481Sjb 640178481Sjb /* define a new type */ 641178481Sjb cp = tdefdecl(cp, h2, rtdp); 642178481Sjb if ((*rtdp)->t_id && (*rtdp)->t_id != h2) { 643178481Sjb ntdp = calloc(sizeof (*ntdp), 1); 644178481Sjb ntdp->t_type = TYPEDEF; 645178481Sjb ntdp->t_tdesc = *rtdp; 646178481Sjb *rtdp = ntdp; 647178481Sjb } 648178481Sjb 649178481Sjb addhash(*rtdp, h2); 650178481Sjb 651178481Sjb } else { /* that type is already defined */ 652178481Sjb if (ntdp->t_type != TYPEDEF || ntdp->t_name != NULL) { 653178481Sjb *rtdp = ntdp; 654178481Sjb } else { 655178481Sjb parse_debug(3, NULL, 656178481Sjb "No duplicate typedef anon for ref"); 657178481Sjb *rtdp = ntdp; 658178481Sjb } 659178481Sjb } 660178481Sjb break; 661178481Sjb case '*': 662178481Sjb ntdp = NULL; 663178481Sjb cp = tdefdecl(cp + 1, h, &ntdp); 664178481Sjb if (ntdp == NULL) 665178481Sjb expected("tdefdecl/*", "id", cp); 666178481Sjb 667178481Sjb if (!ntdp->t_id) 668178481Sjb ntdp->t_id = faketypenumber++; 669178481Sjb 670178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 671178481Sjb (*rtdp)->t_type = POINTER; 672178481Sjb (*rtdp)->t_size = 0; 673178481Sjb (*rtdp)->t_id = h; 674178481Sjb (*rtdp)->t_tdesc = ntdp; 675178481Sjb break; 676178481Sjb case 'f': 677178481Sjb cp = tdefdecl(cp + 1, h, &ntdp); 678178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 679178481Sjb (*rtdp)->t_type = FUNCTION; 680178481Sjb (*rtdp)->t_size = 0; 681178481Sjb (*rtdp)->t_id = h; 682178481Sjb (*rtdp)->t_fndef = xcalloc(sizeof (fndef_t)); 683178481Sjb /* 684178481Sjb * The 6.1 compiler will sometimes generate incorrect stabs for 685178481Sjb * function pointers (it'll get the return type wrong). This 686178481Sjb * causes merges to fail. We therefore treat function pointers 687178481Sjb * as if they all point to functions that return int. When 688178481Sjb * 4432549 is fixed, the lookupname() call below should be 689178481Sjb * replaced with `ntdp'. 690178481Sjb */ 691178481Sjb (*rtdp)->t_fndef->fn_ret = lookupname("int"); 692178481Sjb break; 693178481Sjb case 'a': 694178481Sjb case 'z': 695178481Sjb cp++; 696178481Sjb if (*cp++ != 'r') 697178481Sjb expected("tdefdecl/[az]", "r", cp - 1); 698178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 699178481Sjb (*rtdp)->t_type = ARRAY; 700178481Sjb (*rtdp)->t_id = h; 701178481Sjb cp = arraydef(cp, rtdp); 702178481Sjb break; 703178481Sjb case 'x': 704178481Sjb c = *++cp; 705178481Sjb if (c != 's' && c != 'u' && c != 'e') 706178481Sjb expected("tdefdecl/x", "[sue]", cp - 1); 707178481Sjb cp = name(cp + 1, &w); 708178481Sjb 709178481Sjb ntdp = xcalloc(sizeof (*ntdp)); 710178481Sjb ntdp->t_type = FORWARD; 711178481Sjb ntdp->t_name = w; 712178481Sjb /* 713178481Sjb * We explicitly don't set t_id here - the caller will do it. 714178481Sjb * The caller may want to use a real type ID, or they may 715178481Sjb * choose to make one up. 716178481Sjb */ 717178481Sjb 718178481Sjb *rtdp = ntdp; 719178481Sjb break; 720178481Sjb 721178481Sjb case 'B': /* volatile */ 722178481Sjb cp = tdefdecl(cp + 1, h, &ntdp); 723178481Sjb 724178481Sjb if (!ntdp->t_id) 725178481Sjb ntdp->t_id = faketypenumber++; 726178481Sjb 727178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 728178481Sjb (*rtdp)->t_type = VOLATILE; 729178481Sjb (*rtdp)->t_size = 0; 730178481Sjb (*rtdp)->t_tdesc = ntdp; 731178481Sjb (*rtdp)->t_id = h; 732178481Sjb break; 733178481Sjb 734178481Sjb case 'k': /* const */ 735178481Sjb cp = tdefdecl(cp + 1, h, &ntdp); 736178481Sjb 737178481Sjb if (!ntdp->t_id) 738178481Sjb ntdp->t_id = faketypenumber++; 739178481Sjb 740178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 741178481Sjb (*rtdp)->t_type = CONST; 742178481Sjb (*rtdp)->t_size = 0; 743178481Sjb (*rtdp)->t_tdesc = ntdp; 744178481Sjb (*rtdp)->t_id = h; 745178481Sjb break; 746178481Sjb 747178481Sjb case 'K': /* restricted */ 748178481Sjb cp = tdefdecl(cp + 1, h, &ntdp); 749178481Sjb 750178481Sjb if (!ntdp->t_id) 751178481Sjb ntdp->t_id = faketypenumber++; 752178481Sjb 753178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 754178481Sjb (*rtdp)->t_type = RESTRICT; 755178481Sjb (*rtdp)->t_size = 0; 756178481Sjb (*rtdp)->t_tdesc = ntdp; 757178481Sjb (*rtdp)->t_id = h; 758178481Sjb break; 759178481Sjb 760178481Sjb case 'u': 761178481Sjb case 's': 762178481Sjb cp++; 763178481Sjb 764178481Sjb *rtdp = xcalloc(sizeof (**rtdp)); 765178481Sjb (*rtdp)->t_name = NULL; 766178481Sjb cp = soudef(cp, (type == 'u') ? UNION : STRUCT, rtdp); 767178481Sjb break; 768178481Sjb default: 769178481Sjb expected("tdefdecl", "<type code>", cp); 770178481Sjb } 771178481Sjb return (cp); 772178481Sjb} 773178481Sjb 774178481Sjbstatic char * 775178481Sjbintrinsic(char *cp, tdesc_t **rtdp) 776178481Sjb{ 777178481Sjb intr_t *intr = xcalloc(sizeof (intr_t)); 778178481Sjb tdesc_t *tdp; 779178481Sjb int width, fmt, i; 780178481Sjb 781178481Sjb switch (*cp++) { 782178481Sjb case 'b': 783178481Sjb intr->intr_type = INTR_INT; 784178481Sjb if (*cp == 's') 785178481Sjb intr->intr_signed = 1; 786178481Sjb else if (*cp != 'u') 787178481Sjb expected("intrinsic/b", "[su]", cp); 788178481Sjb cp++; 789178481Sjb 790178481Sjb if (strchr("cbv", *cp)) 791178481Sjb intr->intr_iformat = *cp++; 792178481Sjb 793178481Sjb cp = number(cp, &width); 794178481Sjb if (*cp++ != ';') 795178481Sjb expected("intrinsic/b", "; (post-width)", cp - 1); 796178481Sjb 797178481Sjb cp = number(cp, &intr->intr_offset); 798178481Sjb if (*cp++ != ';') 799178481Sjb expected("intrinsic/b", "; (post-offset)", cp - 1); 800178481Sjb 801178481Sjb cp = number(cp, &intr->intr_nbits); 802178481Sjb break; 803178481Sjb 804178481Sjb case 'R': 805178481Sjb intr->intr_type = INTR_REAL; 806178481Sjb for (fmt = 0, i = 0; isdigit(*(cp + i)); i++) 807178481Sjb fmt = fmt * 10 + (*(cp + i) - '0'); 808178481Sjb 809178481Sjb if (fmt < 1 || fmt > CTF_FP_MAX) 810178481Sjb expected("intrinsic/R", "number <= CTF_FP_MAX", cp); 811178481Sjb 812178481Sjb intr->intr_fformat = fmt; 813178481Sjb cp += i; 814178481Sjb 815178481Sjb if (*cp++ != ';') 816178481Sjb expected("intrinsic/R", ";", cp - 1); 817178481Sjb cp = number(cp, &width); 818178481Sjb 819178481Sjb intr->intr_nbits = width * 8; 820178481Sjb break; 821178481Sjb } 822178481Sjb 823178481Sjb tdp = xcalloc(sizeof (*tdp)); 824178481Sjb tdp->t_type = INTRINSIC; 825178481Sjb tdp->t_size = width; 826178481Sjb tdp->t_name = NULL; 827178481Sjb tdp->t_intr = intr; 828178481Sjb parse_debug(3, NULL, "intrinsic: size=%d", width); 829178481Sjb *rtdp = tdp; 830178481Sjb 831178481Sjb return (cp); 832178481Sjb} 833178481Sjb 834178481Sjbstatic tdesc_t * 835178481Sjbbitintrinsic(tdesc_t *template, int nbits) 836178481Sjb{ 837178481Sjb tdesc_t *newtdp = xcalloc(sizeof (tdesc_t)); 838178481Sjb 839178481Sjb newtdp->t_name = xstrdup(template->t_name); 840178481Sjb newtdp->t_id = faketypenumber++; 841178481Sjb newtdp->t_type = INTRINSIC; 842178481Sjb newtdp->t_size = template->t_size; 843178481Sjb newtdp->t_intr = xmalloc(sizeof (intr_t)); 844178481Sjb bcopy(template->t_intr, newtdp->t_intr, sizeof (intr_t)); 845178481Sjb newtdp->t_intr->intr_nbits = nbits; 846178481Sjb 847178481Sjb return (newtdp); 848178481Sjb} 849178481Sjb 850178481Sjbstatic char * 851178481Sjboffsize(char *cp, mlist_t *mlp) 852178481Sjb{ 853178481Sjb int offset, size; 854178481Sjb 855178481Sjb if (*cp == ',') 856178481Sjb cp++; 857178481Sjb cp = number(cp, &offset); 858178481Sjb if (*cp++ != ',') 859178481Sjb expected("offsize/2", ",", cp - 1); 860178481Sjb cp = number(cp, &size); 861178481Sjb if (*cp++ != ';') 862178481Sjb expected("offsize/3", ";", cp - 1); 863178481Sjb mlp->ml_offset = offset; 864178481Sjb mlp->ml_size = size; 865178481Sjb return (cp); 866178481Sjb} 867178481Sjb 868178481Sjbstatic tdesc_t * 869178481Sjbfind_intrinsic(tdesc_t *tdp) 870178481Sjb{ 871178481Sjb for (;;) { 872178481Sjb switch (tdp->t_type) { 873178481Sjb case TYPEDEF: 874178481Sjb case VOLATILE: 875178481Sjb case CONST: 876178481Sjb case RESTRICT: 877178481Sjb tdp = tdp->t_tdesc; 878178481Sjb break; 879178481Sjb 880178481Sjb default: 881178481Sjb return (tdp); 882178481Sjb } 883178481Sjb } 884178481Sjb} 885178481Sjb 886178481Sjbstatic char * 887178481Sjbsoudef(char *cp, stabtype_t type, tdesc_t **rtdp) 888178481Sjb{ 889178481Sjb mlist_t *mlp, **prev; 890178481Sjb char *w; 891178481Sjb int h; 892178481Sjb int size; 893178481Sjb tdesc_t *tdp, *itdp; 894178481Sjb 895178481Sjb cp = number(cp, &size); 896178481Sjb (*rtdp)->t_size = size; 897178481Sjb (*rtdp)->t_type = type; /* s or u */ 898178481Sjb 899178481Sjb /* 900178481Sjb * An '@' here indicates a bitmask follows. This is so the 901178481Sjb * compiler can pass information to debuggers about how structures 902178481Sjb * are passed in the v9 world. We don't need this information 903178481Sjb * so we skip over it. 904178481Sjb */ 905178481Sjb if (cp[0] == '@') { 906178481Sjb cp += 3; 907178481Sjb } 908178481Sjb 909178481Sjb parse_debug(3, cp, "soudef: %s size=%d", tdesc_name(*rtdp), 910178481Sjb (*rtdp)->t_size); 911178481Sjb 912178481Sjb prev = &((*rtdp)->t_members); 913178481Sjb /* now fill up the fields */ 914178481Sjb while ((*cp != '\0') && (*cp != ';')) { /* signifies end of fields */ 915178481Sjb mlp = xcalloc(sizeof (*mlp)); 916178481Sjb *prev = mlp; 917178481Sjb cp = name(cp, &w); 918178481Sjb mlp->ml_name = w; 919178481Sjb cp = id(cp, &h); 920178481Sjb /* 921178481Sjb * find the tdesc struct in the hash table for this type 922178481Sjb * and stick a ptr in here 923178481Sjb */ 924178481Sjb tdp = lookup(h); 925178481Sjb if (tdp == NULL) { /* not in hash list */ 926178481Sjb parse_debug(3, NULL, " defines %s (%d)", w, h); 927178481Sjb if (*cp++ != '=') { 928178481Sjb tdp = unres_new(h); 929178481Sjb parse_debug(3, NULL, 930178481Sjb " refers to %s (unresolved %d)", 931178481Sjb (w ? w : "anon"), h); 932178481Sjb } else { 933178481Sjb cp = tdefdecl(cp, h, &tdp); 934178481Sjb 935178481Sjb if (tdp->t_id && tdp->t_id != h) { 936178481Sjb tdesc_t *ntdp = xcalloc(sizeof (*ntdp)); 937178481Sjb 938178481Sjb ntdp->t_type = TYPEDEF; 939178481Sjb ntdp->t_tdesc = tdp; 940178481Sjb tdp = ntdp; 941178481Sjb } 942178481Sjb 943178481Sjb addhash(tdp, h); 944178481Sjb parse_debug(4, cp, 945178481Sjb " soudef now looking at "); 946178481Sjb cp++; 947178481Sjb } 948178481Sjb } else { 949178481Sjb parse_debug(3, NULL, " refers to %s (%d, %s)", 950178481Sjb w ? w : "anon", h, tdesc_name(tdp)); 951178481Sjb } 952178481Sjb 953178481Sjb cp = offsize(cp, mlp); 954178481Sjb 955178481Sjb itdp = find_intrinsic(tdp); 956178481Sjb if (itdp->t_type == INTRINSIC) { 957178481Sjb if (mlp->ml_size != itdp->t_intr->intr_nbits) { 958178481Sjb parse_debug(4, cp, "making %d bit intrinsic " 959178481Sjb "from %s", mlp->ml_size, tdesc_name(itdp)); 960178481Sjb mlp->ml_type = bitintrinsic(itdp, mlp->ml_size); 961178481Sjb } else 962178481Sjb mlp->ml_type = tdp; 963178481Sjb } else if (itdp->t_type == TYPEDEF_UNRES) { 964178481Sjb list_add(&typedbitfldmems, mlp); 965178481Sjb mlp->ml_type = tdp; 966178481Sjb } else { 967178481Sjb mlp->ml_type = tdp; 968178481Sjb } 969178481Sjb 970178481Sjb /* cp is now pointing to next field */ 971178481Sjb prev = &mlp->ml_next; 972178481Sjb } 973178481Sjb return (cp); 974178481Sjb} 975178481Sjb 976178481Sjbstatic char * 977178481Sjbarraydef(char *cp, tdesc_t **rtdp) 978178481Sjb{ 979178481Sjb int start, end, h; 980178481Sjb 981178481Sjb cp = id(cp, &h); 982178481Sjb if (*cp++ != ';') 983178481Sjb expected("arraydef/1", ";", cp - 1); 984178481Sjb 985178481Sjb (*rtdp)->t_ardef = xcalloc(sizeof (ardef_t)); 986178481Sjb (*rtdp)->t_ardef->ad_idxtype = lookup(h); 987178481Sjb 988178481Sjb cp = number(cp, &start); /* lower */ 989178481Sjb if (*cp++ != ';') 990178481Sjb expected("arraydef/2", ";", cp - 1); 991178481Sjb 992178481Sjb if (*cp == 'S') { 993178481Sjb /* variable length array - treat as null dimensioned */ 994178481Sjb cp++; 995178481Sjb if (*cp++ != '-') 996178481Sjb expected("arraydef/fpoff-sep", "-", cp - 1); 997178481Sjb cp = number(cp, &end); 998178481Sjb end = start; 999178481Sjb } else { 1000178481Sjb /* normal fixed-dimension array */ 1001178481Sjb cp = number(cp, &end); /* upper */ 1002178481Sjb } 1003178481Sjb 1004178481Sjb if (*cp++ != ';') 1005178481Sjb expected("arraydef/3", ";", cp - 1); 1006178481Sjb (*rtdp)->t_ardef->ad_nelems = end - start + 1; 1007178481Sjb cp = tdefdecl(cp, h, &((*rtdp)->t_ardef->ad_contents)); 1008178481Sjb 1009178481Sjb parse_debug(3, cp, "defined array idx type %d %d-%d next ", 1010178481Sjb h, start, end); 1011178481Sjb 1012178481Sjb return (cp); 1013178481Sjb} 1014178481Sjb 1015178481Sjbstatic void 1016178481Sjbenumdef(char *cp, tdesc_t **rtdp) 1017178481Sjb{ 1018178481Sjb elist_t *elp, **prev; 1019178481Sjb char *w; 1020178481Sjb 1021178481Sjb (*rtdp)->t_type = ENUM; 1022178481Sjb (*rtdp)->t_emem = NULL; 1023178481Sjb 1024178481Sjb prev = &((*rtdp)->t_emem); 1025178481Sjb while (*cp != ';') { 1026178481Sjb elp = xcalloc(sizeof (*elp)); 1027178481Sjb elp->el_next = NULL; 1028178481Sjb *prev = elp; 1029178481Sjb cp = name(cp, &w); 1030178481Sjb elp->el_name = w; 1031178481Sjb cp = number(cp, &elp->el_number); 1032178481Sjb parse_debug(3, NULL, "enum %s: %s=%d", tdesc_name(*rtdp), 1033178481Sjb elp->el_name, elp->el_number); 1034178481Sjb prev = &elp->el_next; 1035178481Sjb if (*cp++ != ',') 1036178481Sjb expected("enumdef", ",", cp - 1); 1037178481Sjb } 1038178481Sjb} 1039178481Sjb 1040178481Sjbstatic tdesc_t * 1041178481Sjblookup_name(tdesc_t **hash, const char *name1) 1042178481Sjb{ 1043178481Sjb int bucket = compute_sum(name1); 1044178481Sjb tdesc_t *tdp, *ttdp = NULL; 1045178481Sjb 1046178481Sjb for (tdp = hash[bucket]; tdp != NULL; tdp = tdp->t_next) { 1047178481Sjb if (tdp->t_name != NULL && strcmp(tdp->t_name, name1) == 0) { 1048178481Sjb if (tdp->t_type == STRUCT || tdp->t_type == UNION || 1049178481Sjb tdp->t_type == ENUM || tdp->t_type == INTRINSIC) 1050178481Sjb return (tdp); 1051178481Sjb if (tdp->t_type == TYPEDEF) 1052178481Sjb ttdp = tdp; 1053178481Sjb } 1054178481Sjb } 1055178481Sjb return (ttdp); 1056178481Sjb} 1057178481Sjb 1058178481Sjbtdesc_t * 1059178481Sjblookupname(const char *name1) 1060178481Sjb{ 1061178481Sjb return (lookup_name(name_table, name1)); 1062178481Sjb} 1063178481Sjb 1064178481Sjb/* 1065178481Sjb * Add a node to the hash queues. 1066178481Sjb */ 1067178481Sjbstatic void 1068178481Sjbaddhash(tdesc_t *tdp, int num) 1069178481Sjb{ 1070178481Sjb int hash = HASH(num); 1071178481Sjb tdesc_t *ttdp; 1072178481Sjb char added_num = 0, added_name = 0; 1073178481Sjb 1074178481Sjb /* 1075178481Sjb * If it already exists in the hash table don't add it again 1076178481Sjb * (but still check to see if the name should be hashed). 1077178481Sjb */ 1078178481Sjb ttdp = lookup(num); 1079178481Sjb 1080178481Sjb if (ttdp == NULL) { 1081178481Sjb tdp->t_id = num; 1082178481Sjb tdp->t_hash = hash_table[hash]; 1083178481Sjb hash_table[hash] = tdp; 1084178481Sjb added_num = 1; 1085178481Sjb } 1086178481Sjb 1087178481Sjb if (tdp->t_name != NULL) { 1088178481Sjb ttdp = lookupname(tdp->t_name); 1089178481Sjb if (ttdp == NULL) { 1090178481Sjb hash = compute_sum(tdp->t_name); 1091178481Sjb tdp->t_next = name_table[hash]; 1092178481Sjb name_table[hash] = tdp; 1093178481Sjb added_name = 1; 1094178481Sjb } 1095178481Sjb } 1096178481Sjb if (!added_num && !added_name) { 1097178481Sjb terminate("stabs: broken hash\n"); 1098178481Sjb } 1099178481Sjb} 1100178481Sjb 1101178481Sjbstatic int 1102178481Sjbcompute_sum(const char *w) 1103178481Sjb{ 1104178481Sjb char c; 1105178481Sjb int sum; 1106178481Sjb 1107178481Sjb for (sum = 0; (c = *w) != '\0'; sum += c, w++) 1108178481Sjb ; 1109178481Sjb return (HASH(sum)); 1110178481Sjb} 1111178481Sjb 1112178481Sjbstatic void 1113178481Sjbreset(void) 1114178481Sjb{ 1115178481Sjb longjmp(resetbuf, 1); 1116178481Sjb} 1117178481Sjb 1118178481Sjbvoid 1119178481Sjbcheck_hash(void) 1120178481Sjb{ 1121178481Sjb tdesc_t *tdp; 1122178481Sjb int i; 1123178481Sjb 1124178481Sjb printf("checking hash\n"); 1125178481Sjb for (i = 0; i < BUCKETS; i++) { 1126178481Sjb if (hash_table[i]) { 1127178481Sjb for (tdp = hash_table[i]->t_hash; 1128178481Sjb tdp && tdp != hash_table[i]; 1129178481Sjb tdp = tdp->t_hash) 1130178481Sjb continue; 1131178481Sjb if (tdp) { 1132178481Sjb terminate("cycle in hash bucket %d\n", i); 1133178481Sjb return; 1134178481Sjb } 1135178481Sjb } 1136178481Sjb 1137178481Sjb if (name_table[i]) { 1138178481Sjb for (tdp = name_table[i]->t_next; 1139178481Sjb tdp && tdp != name_table[i]; 1140178481Sjb tdp = tdp->t_next) 1141178481Sjb continue; 1142178481Sjb if (tdp) { 1143178481Sjb terminate("cycle in name bucket %d\n", i); 1144178481Sjb return; 1145178481Sjb } 1146178481Sjb } 1147178481Sjb } 1148178481Sjb printf("done\n"); 1149178481Sjb} 1150178481Sjb 1151178481Sjb/*ARGSUSED1*/ 1152178481Sjbstatic int 1153178481Sjbresolve_typed_bitfields_cb(void *arg, void *private __unused) 1154178481Sjb{ 1155178481Sjb mlist_t *ml = arg; 1156178481Sjb tdesc_t *tdp = ml->ml_type; 1157178481Sjb 1158178481Sjb debug(3, "Resolving typed bitfields (member %s)\n", 1159178481Sjb (ml->ml_name ? ml->ml_name : "(anon)")); 1160178481Sjb 1161178481Sjb while (tdp) { 1162178481Sjb switch (tdp->t_type) { 1163178481Sjb case INTRINSIC: 1164178481Sjb if (ml->ml_size != tdp->t_intr->intr_nbits) { 1165178481Sjb debug(3, "making %d bit intrinsic from %s", 1166178481Sjb ml->ml_size, tdesc_name(tdp)); 1167178481Sjb ml->ml_type = bitintrinsic(tdp, ml->ml_size); 1168178481Sjb } else { 1169178481Sjb debug(3, "using existing %d bit %s intrinsic", 1170178481Sjb ml->ml_size, tdesc_name(tdp)); 1171178481Sjb ml->ml_type = tdp; 1172178481Sjb } 1173178481Sjb return (1); 1174178481Sjb 1175178481Sjb case POINTER: 1176178481Sjb case TYPEDEF: 1177178481Sjb case VOLATILE: 1178178481Sjb case CONST: 1179178481Sjb case RESTRICT: 1180178481Sjb tdp = tdp->t_tdesc; 1181178481Sjb break; 1182178481Sjb 1183178481Sjb default: 1184178481Sjb return (1); 1185178481Sjb } 1186178481Sjb } 1187178481Sjb 1188178481Sjb terminate("type chain for bitfield member %s has a NULL", ml->ml_name); 1189178481Sjb /*NOTREACHED*/ 1190178481Sjb return (0); 1191178481Sjb} 1192178481Sjb 1193178481Sjbvoid 1194178481Sjbresolve_typed_bitfields(void) 1195178481Sjb{ 1196178481Sjb (void) list_iter(typedbitfldmems, 1197178481Sjb resolve_typed_bitfields_cb, NULL); 1198178481Sjb} 1199