|
|
1.1 ! root 1: /* ! 2: * static char addr1_ID[] = "@(#) addr1.c: 1.6 12/10/83"; ! 3: */ ! 4: ! 5: #include <stdio.h> ! 6: #include <filehdr.h> ! 7: #include <reloc.h> ! 8: #include <syms.h> ! 9: #include <linenum.h> ! 10: #include "systems.h" ! 11: #include "gendefs.h" ! 12: #include "symbols.h" ! 13: #include "codeout.h" ! 14: ! 15: /* ! 16: * ! 17: * "addr1.c" is a file containing routines for implementing the ! 18: * various addressing modes from the intermediate file. The ! 19: * majority of the routines are passed a pointer to a ! 20: * character string and a pointer to the code buffer. ! 21: * The array "modes" is initialized to contain the addresses ! 22: * of the functions that implement the various addressing modes. ! 23: * Indexing this array with the addressing mode will give the ! 24: * correct routine for implementing that mode. ! 25: * ! 26: */ ! 27: ! 28: #define outblock(a,b,c) fwrite((char *)(a),b,1,c) ! 29: ! 30: extern char ! 31: cfile[]; ! 32: ! 33: extern unsigned short ! 34: line, ! 35: cline; ! 36: ! 37: extern short ! 38: type, ! 39: transvec, ! 40: sttop; ! 41: ! 42: extern int ! 43: setsym(); ! 44: ! 45: extern long ! 46: newdot, ! 47: symbent, ! 48: gsymbent; ! 49: ! 50: extern long ! 51: getindx(); ! 52: ! 53: extern symbol ! 54: *dot; ! 55: ! 56: extern FILHDR ! 57: filhead; ! 58: ! 59: extern upsymins ! 60: *lookup(); ! 61: ! 62: extern stent ! 63: *pop(); ! 64: static stent ! 65: *popptr; ! 66: ! 67: extern FILE ! 68: #if !ONEPROC ! 69: *fdstring, ! 70: #endif ! 71: *fdline, ! 72: *fdsymb, ! 73: *fdgsymb; ! 74: ! 75: symbol *savsym; ! 76: ! 77: unsigned short ! 78: lineent; ! 79: ! 80: short filedef = NO; ! 81: ! 82: #if FLEXNAMES ! 83: extern char *strtab; /* String table; referenced for symbol */ ! 84: /* name to pass to getindx. */ ! 85: #endif ! 86: ! 87: SYMENT sment; ! 88: ! 89: AUXENT axent; ! 90: ! 91: static short ! 92: dimcnt; ! 93: ! 94: static LINENO ! 95: lnent; ! 96: ! 97: /*ARGSUSED*/ ! 98: ! 99: setmagic(sym,code) ! 100: symbol *sym; ! 101: codebuf *code; ! 102: { ! 103: filhead.f_magic = (short)(code->cvalue); ! 104: } ! 105: ! 106: setfile(sym,code) ! 107: upsymins sym; ! 108: codebuf *code; ! 109: { ! 110: register char c; ! 111: register char *auxchar; ! 112: register short index = 0; ! 113: ! 114: filedef = YES; ! 115: ! 116: sym = *lookup(".file",INSTALL,USRNAME); ! 117: define(sym.stp,code); ! 118: ! 119: sment.n_numaux = 1; ! 120: auxchar = ((union auxent *)(&axent))->x_file.x_fname; ! 121: #if ONEPROC ! 122: while (*auxchar++ = cfile[index++]) ; ! 123: #else ! 124: while (((c = getc(fdstring)) != '\n') && (index < FILNMLEN)) { ! 125: *auxchar++ = c; ! 126: cfile[index++] = c; ! 127: } ! 128: #endif ! 129: for ( ; index < FILNMLEN; index++) ! 130: *auxchar++ = '\0'; ! 131: ! 132: cfile[index] = '\0'; ! 133: code->cvalue = (long)C_FILE; ! 134: setscl(NULLSYM,code); ! 135: endef(NULLSYM,code); ! 136: } /* setfile */ ! 137: ! 138: /*ARGSUSED*/ ! 139: ! 140: newstmt(sym,code) ! 141: symbol *sym; ! 142: codebuf *code; ! 143: { ! 144: line = (unsigned short)(code->cvalue); ! 145: dot->value = newdot; /* resynchronize */ ! 146: } /* newstmt */ ! 147: ! 148: /* ! 149: * ! 150: * "lineno" is a function that creates a line number entry with ! 151: * the value of the program counter. A preliminary line number ! 152: * entry is created by writing to the file whose descriptor ! 153: * appears in "fdline". The preliminary line number entry contains ! 154: * the value of the program counter and the line number itself. ! 155: * ! 156: */ ! 157: ! 158: lineno(sym,code) ! 159: register symbol *sym; ! 160: register codebuf *code; ! 161: { ! 162: if (sym != NULLSYM) ! 163: code->cvalue += sym->value; ! 164: lnent.l_lnno = cline = (unsigned short)(code->cvalue); ! 165: lnent.l_addr.l_paddr = newdot; ! 166: outblock(&lnent,LINESZ,fdline); ! 167: lineent++; ! 168: } ! 169: ! 170: /* ! 171: * ! 172: * "linenum" and "lineval" work in a pair to implement the two ! 173: * operand version of the ".ln" pseudo operation. This operation ! 174: * will generate two intermediate file entries. "linenum" ! 175: * evaluates the line number and stores it in the global ! 176: * variable "savline". "lineval" evaluates its argument to ! 177: * use it as the address for the line number. This address ! 178: * and the line number from "savline" are written to the file ! 179: * whose descriptor appears in "fdline" as a completed line ! 180: * number entry. ! 181: * ! 182: */ ! 183: ! 184: linenum(sym,code) ! 185: register symbol *sym; ! 186: register codebuf *code; ! 187: { ! 188: if (sym != NULLSYM) ! 189: code->cvalue += sym->value; ! 190: lnent.l_lnno = cline = (unsigned short)(code->cvalue); ! 191: } ! 192: ! 193: lineval(sym,code) ! 194: register symbol *sym; ! 195: register codebuf *code; ! 196: { ! 197: if (sym != NULLSYM) ! 198: code->cvalue += sym->value; ! 199: lnent.l_addr.l_paddr = code->cvalue; ! 200: outblock(&lnent,LINESZ,fdline); ! 201: lineent++; ! 202: } ! 203: ! 204: /* ! 205: * ! 206: * The functions "define", "setval", "settyp", "setscl", "settag", ! 207: * "setlno", "setsiz", "setdim1" through "setdim5", "xform", and ! 208: * "endef" are all involved in creating the symbol table entries ! 209: * that appear in the object file. The call to "define" will ! 210: * initialize the symbol table entry. The calls to subsequent ! 211: * functions will store values into various fields of that entry. ! 212: * The call to "endef" will write out the completed symbol table ! 213: * entry to an intermediate file. The symbol table entry will be ! 214: * constructed in a structure called "sment". The auxiliary ! 215: * symbol table entry (if necessary) will be constructed in the ! 216: * structure "axent". The completed symbol table entry will be ! 217: * written either to the file whose descriptor appears in "fdsymb" ! 218: * or the file whose descriptor appears in "fdgsymb". ! 219: * ! 220: */ ! 221: ! 222: /* ! 223: * ! 224: * "define" is a function that performs initialization of a symbol ! 225: * table entry to be written to the object file. ! 226: * The arguments to this function is a pointer to the symbol for ! 227: * which the entry is to be created. The symbol name is stored ! 228: * into the object file symbol table entry, and the remainder ! 229: * of the fields for the entry are set to zero. ! 230: * ! 231: */ ! 232: ! 233: /*ARGSUSED*/ ! 234: ! 235: define(sym,code) ! 236: register symbol *sym; ! 237: codebuf *code; ! 238: { ! 239: register short index; ! 240: ! 241: savsym = sym; ! 242: #if FLEXNAMES ! 243: /* Copy the internal symbol table entry for the name to the */ ! 244: /* structure which will be written to the symbol table file. */ ! 245: ! 246: if (sym->_name.tabentry.zeroes == 0) ! 247: { ! 248: sment.n_zeroes = 0L; ! 249: sment.n_offset = sym->_name.tabentry.offset; ! 250: } ! 251: else ! 252: { ! 253: #endif ! 254: for(index = 0; (index < SYMNMLEN) && (sment.n_name[index] = sym->_name.name[index]); index++) ! 255: ; ! 256: ! 257: for(; index < SYMNMLEN; index++) ! 258: sment.n_name[index] = '\0'; ! 259: #if FLEXNAMES ! 260: } ! 261: #endif ! 262: sment.n_value = 0L; ! 263: sment.n_scnum = 0; ! 264: sment.n_type = 0; ! 265: sment.n_sclass = 0; ! 266: sment.n_numaux = 0; ! 267: axent.x_sym.x_tagndx = 0L; ! 268: axent.x_sym.x_misc.x_lnsz.x_lnno = 0; ! 269: axent.x_sym.x_misc.x_lnsz.x_size = 0; ! 270: for(index = 0; index < DIMNUM; ++index) ! 271: axent.x_sym.x_fcnary.x_ary.x_dimen[index] = 0; ! 272: axent.x_sym.x_tvndx = 0; ! 273: #if TRANVEC ! 274: if (transvec && (sym->styp & TVDEF)) { ! 275: sment.n_numaux = 1; /* we can do this since transfer */ ! 276: axent.x_sym.x_tvndx = N_TV; /* vectors are always */ ! 277: /* functions in .def's */ ! 278: } ! 279: #endif ! 280: } ! 281: ! 282: /* ! 283: * ! 284: * "setval" is a function that sets the value field of a symbol ! 285: * table entry. The arguments are evaluated and the result is ! 286: * stored into the value field of the symbol table entry, and ! 287: * the section number is set according to the type of the result. ! 288: * ! 289: */ ! 290: ! 291: setval(sym,code) ! 292: register symbol *sym; ! 293: register codebuf *code; ! 294: { ! 295: register short stype; ! 296: ! 297: if (sym != NULLSYM) { ! 298: code->cvalue += sym->value; ! 299: stype = sym->styp & TYPE; ! 300: } ! 301: else ! 302: stype = ABS; ! 303: sment.n_value = code->cvalue; ! 304: switch (stype){ ! 305: case ABS:{ ! 306: sment.n_scnum = N_ABS; ! 307: break; ! 308: } ! 309: case TXT:{ ! 310: sment.n_scnum = 1; ! 311: break; ! 312: } ! 313: case DAT:{ ! 314: sment.n_scnum = 2; ! 315: break; ! 316: } ! 317: case BSS:{ ! 318: sment.n_scnum = 3; ! 319: break; ! 320: } ! 321: } ! 322: } ! 323: ! 324: /* ! 325: * ! 326: * "settyp" is a function that sets the type and derived type ! 327: * field in a symbol table entry. The arguments are evaluated to ! 328: * yield the numeric value to be stored into the type and derived ! 329: * type word. This value is stored into the appropriate field ! 330: * of "sment". ! 331: * ! 332: */ ! 333: ! 334: settyp(sym,code) ! 335: register symbol *sym; ! 336: register codebuf *code; ! 337: { ! 338: if (sym != NULLSYM) ! 339: code->cvalue += sym->value; ! 340: sment.n_type = (short)(code->cvalue); ! 341: } ! 342: ! 343: /* ! 344: * ! 345: * "setscl" is a function that sets the storage class field in a ! 346: * symbol table entry. The arguments are evaluated to yield a ! 347: * value to be stored into the appropriate field of "sment". ! 348: * ! 349: */ ! 350: ! 351: setscl(sym,code) ! 352: register symbol *sym; ! 353: register codebuf *code; ! 354: { ! 355: if (sym != NULLSYM) ! 356: code->cvalue += sym->value; ! 357: sment.n_sclass = (char)(code->cvalue); ! 358: } ! 359: ! 360: /* ! 361: * ! 362: * "settag" is a function that sets the tag field in an auxiliary ! 363: * symbol table entry. The argument to this function is the ! 364: * name of a structure, union, or enumeration tag. This name ! 365: * is passed to "getindx" to obtain the symbol table index of ! 366: * the tag entry. If it is found, a field in the symbol table ! 367: * entry is set indicating the presence of an auxiliary entry ! 368: * and the tag field of the auxiliary entry is set to the index. ! 369: * If the tag was not found, "yyerror" is called to print a ! 370: * diagnostic message. ! 371: * ! 372: */ ! 373: ! 374: /*ARGSUSED*/ ! 375: ! 376: settag(sym,code) ! 377: register symbol *sym; ! 378: codebuf *code; ! 379: { ! 380: register long index; ! 381: char *nameptr; /* We need a pointer to the name string */ ! 382: /* to pass to getindx. */ ! 383: ! 384: #if FLEXNAMES ! 385: if (sym->_name.tabentry.zeroes == 0) ! 386: nameptr = &strtab[sym->_name.tabentry.offset]; ! 387: else ! 388: #endif ! 389: nameptr = sym->_name.name; ! 390: if ( ((index = getindx(nameptr,C_STRTAG)) < 0) && ! 391: ((index = getindx(nameptr,C_UNTAG)) < 0) && ! 392: ((index = getindx(nameptr,C_ENTAG)) < 0)) ! 393: yyerror("Illegal structure, union, or enumeration tag"); ! 394: sment.n_numaux = 1; ! 395: axent.x_sym.x_tagndx = index; ! 396: } ! 397: ! 398: /* ! 399: * ! 400: * "setlno" sets the line number field in an auxiliary symbol ! 401: * table entry. A field is set in the symbol table entry to ! 402: * indicate the presence of an auxiliary entry. The arguments ! 403: * are evaluated to obtain the value of the line number and ! 404: * this value is stored into the appropriate field of the ! 405: * auxiliary symbol table entry. ! 406: * ! 407: * ! 408: */ ! 409: ! 410: setlno(sym,code) ! 411: register symbol *sym; ! 412: register codebuf *code; ! 413: { ! 414: sment.n_numaux = 1; ! 415: if (sym != NULLSYM) ! 416: code->cvalue += sym->value; ! 417: axent.x_sym.x_misc.x_lnsz.x_lnno = (unsigned short)(code->cvalue); ! 418: } ! 419: ! 420: /* ! 421: * ! 422: * "setsiz" sets the size field in an auxiliary symbol table entry. ! 423: * The arguments are evaluated to obtain the size of the object ! 424: * described by this symbol table entry. This value is stored into ! 425: * the appropriate field of the auxiliary symbol table entry and ! 426: * a field is set in the basic symbol table entry to indicate the ! 427: * presence of the auxiliary entry. ! 428: * ! 429: */ ! 430: ! 431: setsiz(sym,code) ! 432: register symbol *sym; ! 433: register codebuf *code; ! 434: { ! 435: sment.n_numaux = 1; ! 436: if (sym != NULLSYM) ! 437: code->cvalue += sym->value; ! 438: axent.x_sym.x_misc.x_lnsz.x_size = (unsigned short)(code->cvalue); ! 439: } ! 440: ! 441: /* indicate that the function was expanded inline */ ! 442: inline(sym,codeptr) ! 443: symbol *sym; ! 444: codebuf *codeptr; ! 445: { ! 446: axent.x_sym.x_misc.x_lnsz.x_size |= 0x1; ! 447: } ! 448: ! 449: /* ! 450: * ! 451: * "setdim1" and "setdim2" set the fields for array dimensions ! 452: * one through four in an auxiliary symbol table entry. The ! 453: * arguments to each function are evaluated to obtain the values ! 454: * for the array dimensions. The function "setdim1" set a field ! 455: * in the basic symbol table entry to indicate the presence of ! 456: * an auxiliary entry. The array dimensions are stored into the ! 457: * appropriate fields of the auxiliary symbol table entry. ! 458: * ! 459: */ ! 460: ! 461: setdim1(sym,code) ! 462: register symbol *sym; ! 463: register codebuf *code; ! 464: { ! 465: sment.n_numaux = 1; ! 466: if (sym != NULLSYM) ! 467: code->cvalue += sym->value; ! 468: axent.x_sym.x_fcnary.x_ary.x_dimen[dimcnt=0] = (unsigned short)(code->cvalue); ! 469: } ! 470: ! 471: setdim2(sym,code) ! 472: register symbol *sym; ! 473: register codebuf *code; ! 474: { ! 475: if (sym != NULLSYM) ! 476: code->cvalue += sym->value; ! 477: if (++dimcnt < DIMNUM) ! 478: axent.x_sym.x_fcnary.x_ary.x_dimen[dimcnt] = (unsigned short)(code->cvalue); ! 479: else ! 480: werror("Too many array dimensions for symbolic debug"); ! 481: } ! 482: ! 483: /* ! 484: * "dfaxent" defines an auxillary entry into the symbol table for ! 485: * the ".text." , ".data" , and ".bss" symbols. It is called from ! 486: * "symout" in file "obj.c". These auxillary entries allow the ! 487: * link editor to know the size of each of these sections in the ! 488: * original source code. ! 489: * ! 490: */ ! 491: ! 492: dfaxent(size,nrel,nlin) ! 493: long size; ! 494: unsigned short nrel, ! 495: nlin; ! 496: { ! 497: sment.n_numaux = 1; ! 498: axent.x_scn.x_scnlen = size; ! 499: axent.x_scn.x_nreloc = nrel; ! 500: axent.x_scn.x_nlinno = nlin; ! 501: } ! 502: ! 503: /* ! 504: * ! 505: * "xform" is a function called by "endef" that performs any final ! 506: * transformations necessary on a symbol table entry before it is ! 507: * written out to a temporary file. The present transformations ! 508: * are as follows: ! 509: * ! 510: * 1. The section number for structure tags, union tags, ! 511: * enumeration tags, typedefs, and file names is set to ! 512: * indicate a special symbolic debugging symbol. ! 513: * ! 514: * 2. If the symbol table entry is for a function, a zero ! 515: * line number entry is generated that points to the symbol ! 516: * table entry. The index of the next entry to be ! 517: * generated appears in the global variable "symbent". ! 518: * ! 519: * 3. If the symbol table entry is for a function, a enu- ! 520: * meration tag, a union tag, or a structure tag ! 521: * "setsym" is called to remember the symbol table index ! 522: * for the associated auxiliary entry. ! 523: * ! 524: * 4. If the symbol table entry is for a end block, a ! 525: * end function, or a end of structure, pop is called ! 526: * to enter the symbol table index of the next symbol ! 527: * table entry onto the symbol table element stack. ! 528: * ! 529: */ ! 530: ! 531: xform() ! 532: { ! 533: ! 534: switch (sment.n_sclass) { ! 535: case C_STRTAG: ! 536: case C_UNTAG: ! 537: case C_ENTAG: ! 538: setsym(-1); ! 539: /* No Break */ ! 540: case C_TPDEF: ! 541: case C_FILE: ! 542: sment.n_scnum = N_DEBUG; ! 543: break; ! 544: case C_BLOCK: /* handles ".bb" and ".eb" */ ! 545: if (sment.n_name[1] == 'b') ! 546: setsym(-1); ! 547: else ! 548: pop()->fwdindex = symbent + 1L ! 549: + sment.n_numaux; ! 550: break; ! 551: case C_FCN: /* handles ".bf" and ".ef" */ ! 552: if (sment.n_name[1] == 'e') { ! 553: popptr = pop(); ! 554: popptr->fwdindex = symbent + 1L ! 555: + sment.n_numaux; ! 556: if (sttop > 0) ! 557: aerror("Unbalanced Symbol Table Entries-Too Many Scope Beginnings"); ! 558: } /* ".ef" */ ! 559: break; ! 560: case C_EOS: ! 561: /* get around auxiliary entry */ ! 562: pop()->fwdindex = symbent + 1L + sment.n_numaux; ! 563: break; ! 564: default: ! 565: /* process function entry */ ! 566: if (ISFCN(sment.n_type)) { ! 567: popptr = NULL; ! 568: lnent.l_lnno = 0; ! 569: lnent.l_addr.l_symndx = symbent; ! 570: outblock(&lnent,LINESZ,fdline); ! 571: lineent++; ! 572: sment.n_numaux = 1; ! 573: setsym(0); ! 574: } ! 575: break; ! 576: } /* switch */ ! 577: } /* xform */ ! 578: ! 579: /* ! 580: * ! 581: * "endef" is a function that completes processing of a symbol ! 582: * table entry and writes it out to an intermediate file ! 583: * The arguments to this function are absolutely meaningless. ! 584: * The function "xform" is called to perform any final ! 585: * transformations necessary on the entry. A decision is made ! 586: * as to whether or not the symbol is a global symbol. It is ! 587: * global if the ".def" for it appears in the data section and ! 588: * it has a storage class of "C_EXT". If it is global, the ! 589: * entry will be written to the file whose descriptor appears ! 590: * in "fdgsymb" and the count "gsymbent" will be incremented. ! 591: * If it is not global, the entry will be written to the file ! 592: * whose descriptor appears in "fdsymb" and the count "symbent" ! 593: * will be incremented. ! 594: * ! 595: */ ! 596: ! 597: /*ARGSUSED*/ ! 598: ! 599: endef(sym,code) ! 600: symbol *sym; ! 601: codebuf *code; ! 602: { ! 603: FILE *fd; ! 604: register long *count; ! 605: ! 606: if (sment.n_sclass == (char) C_EFCN) { ! 607: if (popptr == NULL) { ! 608: popptr = pop(); ! 609: popptr->fwdindex = symbent; ! 610: if (sttop > 0) ! 611: aerror("Unbalanced Symbol Table Entries-Too Many Scope Beginnings"); ! 612: } /* popptr == NULL */ ! 613: popptr->fcnlen = newdot - savsym->value; ! 614: /* don't put out this symbol table entry */ ! 615: return; ! 616: } /* sment.n_sclass == C_EFCN */ ! 617: xform(); ! 618: if ((dot->styp == DAT) && (sment.n_sclass == C_EXT)) { ! 619: fd = fdgsymb; ! 620: count = &gsymbent; ! 621: } ! 622: else ! 623: { ! 624: fd = fdsymb; ! 625: count = &symbent; ! 626: putindx(savsym,sment.n_sclass,symbent); ! 627: } ! 628: outblock(&sment,SYMESZ,fd); ! 629: (*count)++; ! 630: if (sment.n_numaux != 0){ ! 631: outblock(&axent,AUXESZ,fd); ! 632: (*count)++; ! 633: } ! 634: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.