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