|
|
1.1 ! root 1: static char ID[] = "@(#) expr1.c: 1.3 3/13/83"; ! 2: #include "system.h" ! 3: ! 4: #include <stdio.h> ! 5: #include "structs.h" ! 6: #include "extrns.h" ! 7: #include "sgsmacros.h" ! 8: #include "y.tab.h" ! 9: #include "ldmacros.h" ! 10: ! 11: static int expsect; ! 12: /*eject*/ ! 13: long ! 14: eval(p) ! 15: ENODE *p; ! 16: { ! 17: ! 18: /* ! 19: * Evaluate an expression node, returning the (long) value of the ! 20: * expression. ! 21: * ! 22: * The extern variable "cur_dot" is used when processing exprs ! 23: * inside of an output section specification, and is set to ! 24: * -1L after allocation, when all sections have been relocated. ! 25: */ ! 26: ! 27: long val1, val2; ! 28: SYMTAB *symp; ! 29: OUTSECT *s; ! 30: ! 31: switch (p->gnode.exop) { ! 32: case INT: ! 33: return( p->vnode.exvalue ); ! 34: case DOT: ! 35: /* ! 36: * Assign to DOT, if not a misuse of the assignment ! 37: */ ! 38: if( p->nnode.exsymptr == 0L ) { ! 39: if( cur_dot == -1L ) { ! 40: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 41: "misuse of DOT symbol in assignment instruction"); ! 42: return (0L); ! 43: } ! 44: return(cur_dot); ! 45: } ! 46: else { ! 47: /* ! 48: * Use of dot in assign to symbol ! 49: */ ! 50: symp = getsym(p->nnode.exsymptr); ! 51: s = (OUTSECT *) symp->smscnptr; ! 52: val1 = symp->sment.n_value + s->oshdr.s_paddr; ! 53: if ( expsect == 0 ) ! 54: expsect = s->ossecnum; ! 55: PUTSYM(symp, 0); ! 56: return (val1); ! 57: } ! 58: case NAME: ! 59: symp = getsym(p->nnode.exsymptr); ! 60: val1 = symp->smnewval; ! 61: if (symp->sment.n_scnum > 0) { ! 62: if(expsect == 0) ! 63: expsect = symp->sment.n_scnum; ! 64: else ! 65: expsect = -1; ! 66: } ! 67: else if( symp->sment.n_scnum == 0 ) ! 68: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 69: "undefined symbol in expression"); ! 70: PUTSYM(symp, 0); ! 71: return (val1); ! 72: case ALIGN: ! 73: if( cur_dot == -1L ) { ! 74: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 75: "ALIGN illegal in this context"); ! 76: return(0L); ! 77: } ! 78: val2 = eval(p->gnode.exleft); ! 79: val1 = (cur_dot + val2 - 1) & (~(val2-1)); ! 80: return(val1); ! 81: ! 82: case PHY: ! 83: /* ! 84: * If (cur_dot != -1L) here, then eval() was ! 85: * called from pboslist(), which is processing ! 86: * the output section list. Moreover, we have ! 87: * an assignment to DOT, because eval() is not ! 88: * called otherwise. The statement is ! 89: * . = ... PHY(...) ... ! 90: * which is invalid. ! 91: */ ! 92: if( cur_dot != -1L ) { ! 93: lderror(1, curexp->evexpr.aiinlnno, ! 94: curexp->evexpr.aiinflnm, ! 95: "illegal assignment of physical address to DOT"); ! 96: return (0L); ! 97: } ! 98: expsect = -1; ! 99: switch( p->gnode.exleft->gnode.exop ) { ! 100: case NAME: ! 101: symp = getsym(p->gnode.exleft->nnode.exsymptr); ! 102: val1 = symp->smnewval; ! 103: if ( symp->smscnptr == NULL ) { ! 104: switch ( symp->sment.n_scnum ) { ! 105: case -1 : /* absolute */ ! 106: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 107: "phy of absolute symbol %s is illegal", ! 108: SYMNAME(symp->sment)); ! 109: break; ! 110: case 0 : /* undefined */ ! 111: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 112: "symbol %s is undefined", ! 113: SYMNAME(symp->sment)); ! 114: break; ! 115: } ! 116: } ! 117: PUTSYM(symp, 0); ! 118: return ( val1 ); ! 119: case DOT: ! 120: if( p->gnode.exleft->nnode.exsymptr == 0L ) { ! 121: lderror(1,curexp->evexpr.aiinlnno, ! 122: curexp->evexpr.aiinflnm, ! 123: "internal error: no symtab entry for DOT"); ! 124: return (0L); ! 125: } ! 126: symp = getsym(p->gnode.exleft->nnode.exsymptr); ! 127: val1 = symp->sment.n_value; ! 128: val1 += ((OUTSECT *) symp->smscnptr)->oshdr.s_paddr; ! 129: ! 130: PUTSYM(symp, 0); ! 131: return ( val1 ); ! 132: default: ! 133: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 134: "operand of PHY must be a name"); ! 135: return(0L); ! 136: } ! 137: ! 138: ! 139: case UMINUS: val1 = eval(p->gnode.exleft); ! 140: return(-val1); ! 141: case NOT: val1 = eval(p->gnode.exleft); ! 142: return(!val1); ! 143: case BNOT: val1 = eval(p->gnode.exleft); ! 144: return(~val1); ! 145: case AND: val1 = eval(p->gnode.exleft); ! 146: val2 = eval(p->gnode.exright); ! 147: return(val1 & val2); ! 148: case ANDAND: val1 = eval(p->gnode.exleft); ! 149: val2 = eval(p->gnode.exright); ! 150: return(val1 && val2); ! 151: case DIV: val1 = eval(p->gnode.exleft); ! 152: val2 = eval(p->gnode.exright); ! 153: return(val1 / val2); ! 154: case EQEQ: val1 = eval(p->gnode.exleft); ! 155: val2 = eval(p->gnode.exright); ! 156: return(val1 == val2); ! 157: case GE: val1 = eval(p->gnode.exleft); ! 158: val2 = eval(p->gnode.exright); ! 159: return(val1 >= val2); ! 160: case GT: val1 = eval(p->gnode.exleft); ! 161: val2 = eval(p->gnode.exright); ! 162: return(val1 > val2); ! 163: case LE: val1 = eval(p->gnode.exleft); ! 164: val2 = eval(p->gnode.exright); ! 165: return(val1 <= val2); ! 166: case LSHIFT: val1 = eval(p->gnode.exleft); ! 167: val2 = eval(p->gnode.exright); ! 168: return(val1 << val2); ! 169: case LT: val1 = eval(p->gnode.exleft); ! 170: val2 = eval(p->gnode.exright); ! 171: return(val1 < val2); ! 172: case MINUS: val1 = eval(p->gnode.exleft); ! 173: val2 = eval(p->gnode.exright); ! 174: return(val1 - val2); ! 175: case MULT: val1 = eval(p->gnode.exleft); ! 176: val2 = eval(p->gnode.exright); ! 177: return(val1 * val2); ! 178: case NE: val1 = eval(p->gnode.exleft); ! 179: val2 = eval(p->gnode.exright); ! 180: return(val1 != val2); ! 181: case OR: val1 = eval(p->gnode.exleft); ! 182: val2 = eval(p->gnode.exright); ! 183: return(val1 | val2); ! 184: case OROR: val1 = eval(p->gnode.exleft); ! 185: val2 = eval(p->gnode.exright); ! 186: return(val1 || val2); ! 187: case PC: val1 = eval(p->gnode.exleft); ! 188: val2 = eval(p->gnode.exright); ! 189: return(val1 % val2); ! 190: case PLUS: val1 = eval(p->gnode.exleft); ! 191: val2 = eval(p->gnode.exright); ! 192: return(val1 + val2); ! 193: case RSHIFT: val1 = eval(p->gnode.exleft); ! 194: val2 = eval(p->gnode.exright); ! 195: return(val1 >> val2); ! 196: ! 197: default: ! 198: lderror(1, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 199: "illegal operator in expression"); ! 200: return(0L); ! 201: } ! 202: } ! 203: /*eject*/ ! 204: pexlist() ! 205: { ! 206: ! 207: /* ! 208: * After allocation, process the "expression list" ! 209: * to define any user-specified symbols. ! 210: */ ! 211: ! 212: #if !ONEPROC ! 213: ACTITEM a; ! 214: #endif ! 215: ! 216: cur_dot = -1L; ! 217: curexp = (ACTITEM *) explist.head; ! 218: ! 219: while( curexp ) { ! 220: ! 221: pexitem(); ! 222: ! 223: clrexp( curexp ); ! 224: ! 225: curexp = curexp->evexpr.ainext; ! 226: ! 227: } ! 228: ! 229: #if DEBUG ! 230: if( dflag > 2 ) ! 231: fprintf( stderr, "\nEXPLIST data structures:" ); ! 232: #endif ! 233: #if !ONEPROC ! 234: while( expcnt-- ) { ! 235: ! 236: fread( &a, 1, sizeof(ACTITEM), trnfdes ); ! 237: a.evexpr.aiinflnm = (char *) ((int) a.evexpr.aiinflnm + (int) strbase); ! 238: ! 239: #if DEBUG ! 240: if( dflag > 2 ) ! 241: fprintf( stderr, "\n\t%04x AIEVEXPR (%s) %d %04x\n\t\tROOT:", ! 242: a.evexpr.ainext, a.evexpr.aiinflnm, ! 243: a.evexpr.aiinlnno, a.evexpr.aiexptr ); ! 244: #endif ! 245: ! 246: curexp = ldexp( &a ); ! 247: ! 248: pexitem(); ! 249: ! 250: clrexp( curexp ); ! 251: ! 252: } ! 253: #endif ! 254: } ! 255: /*eject*/ ! 256: pexitem() ! 257: { ! 258: ! 259: /* ! 260: * Process one assignment instruction ! 261: */ ! 262: ! 263: long val; ! 264: register SYMTAB *sp; ! 265: register OUTSECT *oscn; ! 266: ! 267: expsect = 0; ! 268: val = eval(curexp->evexpr.aiexptr->gnode.exright); ! 269: sp = getsym(curexp->evexpr.aiexptr->gnode.exleft->nnode.exsymptr); ! 270: ! 271: /* ! 272: * If the section number of the symbol we ! 273: * are assigning a value is not zero ( = undefined), ! 274: * the user is redefining the value of the symbol. ! 275: */ ! 276: ! 277: if( sp->sment.n_scnum ) ! 278: if( sp->smscnptr ) ! 279: lderror(0, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 280: "symbol %s from file %s being redefined", ! 281: SYMNAME(sp->sment), sp->smscnptr->isfilptr->flname); ! 282: else ! 283: lderror(0, curexp->evexpr.aiinlnno, curexp->evexpr.aiinflnm, ! 284: "absolute symbol %s being redefined", ! 285: SYMNAME(sp->sment)); ! 286: ! 287: if( expsect == 0 ) ! 288: sp->sment.n_scnum = -1; /* absolute symbol */ ! 289: else ! 290: sp->sment.n_scnum = expsect; ! 291: ! 292: if( (oscn = findoscn(sp->sment.n_scnum)) != NULL ) ! 293: sp->smnewvirt = val - oscn->oshdr.s_paddr + oscn->oshdr.s_vaddr; ! 294: else ! 295: sp->smnewvirt = val; ! 296: sp->smnewval = val; ! 297: sp->sment.n_sclass = C_EXT; ! 298: PUTSYM(sp, 1); ! 299: ! 300: } ! 301: /*eject*/ ! 302: #if !ONEPROC ! 303: ACTITEM * ! 304: ldexp(a) ! 305: ACTITEM *a; ! 306: { ! 307: ! 308: /* ! 309: * Load an assignment instruction from the "transfer file" generated ! 310: * by PASS 1, into memory ! 311: * ! 312: * "a" is the action item which heads the expression tree ! 313: * ! 314: * Return a pointer to a separate copy of this action item ! 315: */ ! 316: ! 317: register ACTITEM *aptr; ! 318: register ENODE *eptr; ! 319: ENODE *ldlimb(); ! 320: ! 321: aptr = (ACTITEM *) myalloc(sizeof(ACTITEM)); ! 322: *aptr = *a; ! 323: ! 324: eptr = (ENODE *) myalloc(sizeof(ENODE)); ! 325: fread( eptr, 1, sizeof(ENODE), trnfdes ); ! 326: ! 327: #if DEBUG ! 328: if( dflag > 2 ) ! 329: fprintf( stderr, "\t%d %04x %04x", (unsigned) eptr->gnode.exop, ! 330: eptr->gnode.exleft, eptr->gnode.exright ); ! 331: #endif ! 332: ! 333: if( eptr->gnode.exleft ) ! 334: eptr->gnode.exleft = ldlimb(); ! 335: if( eptr->gnode.exright ) ! 336: eptr->gnode.exright = ldlimb(); ! 337: ! 338: aptr->evexpr.ainext = NULL; ! 339: aptr->evexpr.aiexptr = eptr; ! 340: ! 341: return( aptr ); ! 342: } ! 343: /*eject*/ ! 344: ENODE * ! 345: ldlimb() ! 346: { ! 347: ! 348: /* ! 349: * Load a non-root node of an expression tree into memory ! 350: */ ! 351: ! 352: register ENODE *eptr; ! 353: SYMENT sym; ! 354: ! 355: eptr = (ENODE *) myalloc(sizeof(ENODE)); ! 356: fread( eptr, 1, sizeof(ENODE), trnfdes ); ! 357: ! 358: switch( (unsigned) eptr->gnode.exop ) { ! 359: case INT: ! 360: #if DEBUG ! 361: if( dflag > 2 ) ! 362: fprintf( stderr, "\n\t\t\tINT %08lx", eptr->vnode.exvalue ); ! 363: #endif ! 364: break; ! 365: case DOT: ! 366: #if DEBUG ! 367: if( dflag > 2 ) ! 368: fprintf( stderr, "\n\t\t\tDOT ()" ); ! 369: #endif ! 370: break; ! 371: case NAME: ! 372: #if DEBUG ! 373: if( dflag > 2 ) ! 374: fprintf( stderr, "\n\t\t\tNAME (%s)", ! 375: eptr->pnnode.symbol ); ! 376: #endif ! 377: zero( (char *) &sym, SYMESZ ); ! 378: #if FLEXNAMES ! 379: if (strlen(eptr->pnnode.symbol) > 8) { ! 380: sym.n_zeroes = 0L; ! 381: sym.n_nptr = eptr->pnnode.symbol; ! 382: } ! 383: else ! 384: #endif ! 385: copy( sym.n_name, eptr->pnnode.symbol, 8); ! 386: sym.n_type = T_INT; ! 387: sym.n_sclass = C_EXT; ! 388: eptr->nnode.exsymptr = putsym( makesym(&sym), 1 ); ! 389: break; ! 390: default: ! 391: #if DEBUG ! 392: if( dflag > 2 ) ! 393: fprintf( stderr, "\n\t\t\t%d %04x %04x", (unsigned) eptr->gnode.exop, ! 394: eptr->gnode.exleft, eptr->gnode.exright ); ! 395: #endif ! 396: if( eptr->gnode.exleft ) ! 397: eptr->gnode.exleft = ldlimb(); ! 398: if( eptr->gnode.exright ) ! 399: eptr->gnode.exright = ldlimb(); ! 400: break; ! 401: } ! 402: ! 403: return( eptr ); ! 404: } ! 405: /*eject*/ ! 406: #endif ! 407: clrexp(a) ! 408: ACTITEM *a; ! 409: { ! 410: ! 411: /* ! 412: * Free up all memory assigned to the assignment instruction pointed ! 413: * to by "a" ! 414: */ ! 415: ENODE *eptr; ! 416: ! 417: eptr = a->evexpr.aiexptr; ! 418: ! 419: switch( (unsigned) eptr->gnode.exop ) { ! 420: case INT: ! 421: case DOT: ! 422: case NAME: ! 423: break; ! 424: default: ! 425: if( eptr->gnode.exleft ) ! 426: clrlimb(eptr->gnode.exleft); ! 427: if( eptr->gnode.exright ) ! 428: clrlimb(eptr->gnode.exright); ! 429: break; ! 430: } ! 431: ! 432: free( eptr ); ! 433: free( a ); ! 434: } ! 435: ! 436: ! 437: ! 438: ! 439: clrlimb(eptr) ! 440: ENODE *eptr; ! 441: { ! 442: ! 443: /* ! 444: * Free up a non-root node of an expression tree ! 445: */ ! 446: ! 447: switch( (unsigned) eptr->gnode.exop ) { ! 448: case INT: ! 449: case DOT: ! 450: case NAME: ! 451: break; ! 452: default: ! 453: if( eptr->gnode.exleft ) ! 454: clrlimb(eptr->gnode.exleft); ! 455: if( eptr->gnode.exright ) ! 456: clrlimb(eptr->gnode.exright); ! 457: break; ! 458: } ! 459: ! 460: free( eptr ); ! 461: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.