|
|
1.1 ! root 1: /* ! 2: * static char ID_sec[] = "@(#) pass2.c: 1.3 3/5/83"; ! 3: */ ! 4: ! 5: #define BSIZE 256 ! 6: ! 7: #include <stdio.h> ! 8: #include "filehdr.h" ! 9: #include "syms.h" ! 10: #include "scnhdr.h" ! 11: #include "linenum.h" ! 12: #include "reloc.h" ! 13: #include "ldfcn.h" ! 14: #include "tagitem.h" ! 15: ! 16: /* pass 2 of the compress utility compresses the symbol table and updates ! 17: all pointers into the symbol table */ ! 18: ! 19: extern LDFILE *oldfile; ! 20: extern FILE *compress; ! 21: extern int copy(); ! 22: ! 23: struct table{ ! 24: long oldlcn; ! 25: long newlcn; ! 26: long real_loc; ! 27: }; ! 28: ! 29: ! 30: secpass(argv, argv2) ! 31: ! 32: char *argv; ! 33: char *argv2; ! 34: { ! 35: ! 36: extern long delsum, tag_sum; ! 37: extern int vflag, pflag; ! 38: extern long szecnt; ! 39: extern struct table *tbl_head; ! 40: long newindx(); ! 41: long proln(); ! 42: long prorel(); ! 43: SCNHDR scptr; ! 44: FILHDR fhead; ! 45: extern LDFILE *ldopen(); ! 46: ! 47: long indx; ! 48: long start; ! 49: long datasze; ! 50: int sumrel; ! 51: int sumln; ! 52: int totsec; ! 53: long frstrel; ! 54: long frstln; ! 55: long onsyms; ! 56: int i; ! 57: ! 58: ! 59: #ifdef FLEXNAMES ! 60: reinit_strings(); ! 61: #endif ! 62: sumrel = sumln = 0; ! 63: indx = 0; ! 64: frstrel = frstln = 0; ! 65: ! 66: /* open files for reading and writing */ ! 67: ! 68: if ((oldfile=ldopen(argv, NULL)) == NULL) { ! 69: fprintf(stderr, "unable to open %s \n", argv); ! 70: return(ERROR); ! 71: } ! 72: ! 73: if ( (compress = fopen(argv2, "w")) == NULL) { ! 74: fprintf(stderr, "unable to create %s\n",argv2); ! 75: return(ERROR); ! 76: } ! 77: ! 78: ! 79: /* read and modify header information */ ! 80: if ( ldfhread(oldfile, &fhead) == FAILURE) { ! 81: if ( vflag > 0) ! 82: fprintf(stderr, "unable to read header\n"); ! 83: return(FAILURE); ! 84: } ! 85: start = HEADER(oldfile).f_symptr; ! 86: onsyms = HEADER(oldfile).f_nsyms; ! 87: fhead.f_nsyms = HEADER(oldfile).f_nsyms - delsum; ! 88: totsec = HEADER(oldfile).f_nscns; ! 89: indx += FILHSZ; ! 90: ! 91: /* copy adjusted header to compress file last */ ! 92: ! 93: if ( fseek(compress, (long)FILHSZ, 0) != 0) { ! 94: if ( vflag > 0) ! 95: fprintf(stderr,"seek past filheader failed\n"); ! 96: return(FAILURE); ! 97: } ! 98: ! 99: /* if there is an optional header copy to compress */ ! 100: ! 101: if ( ldohseek(oldfile) == SUCCESS) { ! 102: if (copy((long)HEADER(oldfile).f_opthdr) != SUCCESS) { ! 103: if ( vflag > 0) ! 104: fprintf(stderr, "ERROR; unable to copy opt header\n"); ! 105: return(FAILURE); ! 106: } ! 107: } ! 108: ! 109: indx += HEADER(oldfile).f_opthdr; ! 110: ! 111: /* read section header information */ ! 112: ! 113: for( i=0; i<totsec; i++) { ! 114: if (fread(&scptr, SCNHSZ, 1, IOPTR(oldfile)) != 1) { ! 115: if ( vflag > 0) ! 116: fprintf(stderr, "read on scnheader failed\n"); ! 117: return(FAILURE); ! 118: } ! 119: ! 120: /* save value for index of first reloc and line sections */ ! 121: ! 122: if (i==0 || frstrel == 0) ! 123: frstrel = scptr.s_relptr; ! 124: if (i == 0 || frstln == 0) ! 125: frstln = scptr.s_lnnoptr; ! 126: sumrel += scptr.s_nreloc; ! 127: sumln += scptr.s_nlnno; ! 128: ! 129: /* copy section information to compress file */ ! 130: ! 131: if ( fwrite(&scptr, SCNHSZ, 1, compress) != 1) { ! 132: if( vflag > 0) ! 133: fprintf(stderr, "write on scnheader failed\n"); ! 134: return(FAILURE); ! 135: } ! 136: indx += SCNHSZ; ! 137: } ! 138: ! 139: ! 140: /* read raw data for all sections and copy to compress */ ! 141: ! 142: if ( sumrel !=0) ! 143: datasze = frstrel - indx; ! 144: else ! 145: if (sumln !=0) ! 146: datasze = frstln - indx; ! 147: else ! 148: datasze = start - indx; ! 149: if ( datasze != 0) ! 150: if (copy((long)datasze) != SUCCESS) { ! 151: if ( vflag > 0) ! 152: fprintf(stderr, "ERROR; unable to copy raw data\n"); ! 153: return(FAILURE); ! 154: } ! 155: indx += datasze; ! 156: ! 157: /* if header flag not set, update relocation section */ ! 158: ! 159: if ( !(HEADER(oldfile).f_flags & F_RELFLG) && sumrel != 0) ! 160: if (( indx = prorel(indx, frstrel, sumrel)) == FAILURE) { ! 161: if ( vflag > 0) ! 162: fprintf(stderr, "indx at prorel wrong\n"); ! 163: return(FAILURE); ! 164: } ! 165: ! 166: /* update linenumber section if flag not set */ ! 167: ! 168: if ( !(HEADER(oldfile).f_flags & F_LNNO) && sumln != 0L) ! 169: if ((indx = proln(indx, frstln, sumln)) == FAILURE) { ! 170: if ( vflag > 0) ! 171: fprintf(stderr, "indx at proln wrong\n"); ! 172: return(FAILURE); ! 173: } ! 174: ! 175: /* call function to modify symbol table */ ! 176: ! 177: if (prosym(indx, onsyms, start) == FAILURE) { ! 178: if ( vflag > 0) ! 179: fprintf(stderr, "prosym returns failure\n"); ! 180: return(FAILURE); ! 181: } ! 182: ! 183: if ( fseek(compress, 0L, 0) != 0) ! 184: if ( vflag > 0) ! 185: fprintf(stderr, "seek to start of object file failed"); ! 186: if (fwrite(&fhead, FILHSZ, 1, compress) != 1) { ! 187: if ( vflag > 0) ! 188: fprintf(stderr, "writing fileheader failed\n"); ! 189: return(FAILURE); ! 190: } ! 191: if ( pflag > 0) ! 192: printf("compression reduces symbol table %ld%%\n", (delsum * 100L) / onsyms); ! 193: /* compression complete; close both files */ ! 194: fclose(compress); ! 195: ldaclose(oldfile); ! 196: return(SUCCESS); ! 197: } ! 198: ! 199: ! 200: /*eject*/ ! 201: /* function "proln" adjust linenumber information for compressed file */ ! 202: ! 203: ! 204: long ! 205: proln(indx,lnindx,lnsum) ! 206: ! 207: long indx, lnindx; ! 208: int lnsum; ! 209: { ! 210: extern long newindx(); ! 211: ! 212: extern int vflag; ! 213: ! 214: struct lineno lnptr; ! 215: int k; ! 216: ! 217: /* verify position of file ptr. */ ! 218: ! 219: if ( indx != lnindx) ! 220: if ( vflag > 0) ! 221: fprintf(stderr, "could not indx to line number \n"); ! 222: for( k=0; k < lnsum; k++) { ! 223: ! 224: if ( FREAD(&lnptr, LINESZ, 1, oldfile) != 1) { ! 225: if ( vflag > 0) ! 226: fprintf(stderr, "cannot read lineno infor\n"); ! 227: return(FAILURE); ! 228: } ! 229: if (lnptr.l_lnno == 0) ! 230: lnptr.l_addr.l_symndx=newindx(lnptr.l_addr.l_symndx); ! 231: if ( fwrite(&lnptr, LINESZ, 1, compress) != 1) { ! 232: if ( vflag > 0) ! 233: fprintf(stderr, "write to lineno failed\n"); ! 234: return(FAILURE); ! 235: } ! 236: indx += LINESZ; ! 237: } ! 238: return(indx); ! 239: } ! 240: ! 241: ! 242: /*eject*/ ! 243: /* function prorel, updates relocation entries for compression *? ! 244: */ ! 245: ! 246: long ! 247: prorel(indx,frstrel,sumrel) ! 248: ! 249: long indx, frstrel; ! 250: int sumrel; ! 251: { ! 252: extern int vflag; ! 253: ! 254: struct reloc relptr; ! 255: long k; ! 256: ! 257: /* verify position of file ptr to start of reloc section */ ! 258: ! 259: if ( indx != frstrel) { ! 260: if ( vflag > 0) ! 261: fprintf(stderr, "error in index computation at reloc\n"); ! 262: exit(1); ! 263: } ! 264: if ( vflag > 0) ! 265: fprintf(stderr, "total number of rel entries = %d\n",sumrel); ! 266: ! 267: for( k=0; k<sumrel; k++) { ! 268: if ( fread(&relptr, RELSZ, 1, IOPTR(oldfile)) < 1) { ! 269: if ( vflag > 0) ! 270: fprintf(stderr, "read rel failed\n"); ! 271: return(FAILURE); ! 272: } ! 273: ! 274: relptr.r_symndx = newindx(relptr.r_symndx); ! 275: if ( fwrite(&relptr, RELSZ, 1, compress) != 1) { ! 276: if ( vflag > 0) ! 277: fprintf(stderr, "write to rel failed\n"); ! 278: return(FAILURE); ! 279: } ! 280: ! 281: indx = indx + RELSZ; ! 282: } ! 283: return(indx); ! 284: } ! 285: ! 286: ! 287: ! 288: /*eject*/ ! 289: ! 290: /* function "newindx" computes newloc for pointers into the symbol table */ ! 291: ! 292: long ! 293: newindx(x) ! 294: ! 295: long x; ! 296: { ! 297: ! 298: extern struct table *tbl_head; ! 299: extern long tag_sum; ! 300: extern long delsum; ! 301: extern int vflag; ! 302: ! 303: struct table *tbl_ptr; ! 304: long i; ! 305: ! 306: /* compare number against old/new/real table, if less than 1st entry ! 307: * return the same value */ ! 308: ! 309: tbl_ptr = tbl_head; ! 310: for (i = 0L; i < tag_sum; i++) { ! 311: if ( x == tbl_ptr->oldlcn) { ! 312: return(tbl_ptr->newlcn); ! 313: } ! 314: if ( x < tbl_ptr->oldlcn) { ! 315: if ( tbl_ptr == tbl_head) ! 316: return(x); ! 317: x -= (tbl_ptr->oldlcn - tbl_ptr->newlcn); ! 318: return(x); ! 319: } ! 320: if ( i == tag_sum-1 && x > tbl_ptr->oldlcn) { ! 321: x -= delsum; ! 322: return(x); ! 323: } ! 324: if ( i != tag_sum-1 ) { ! 325: ++tbl_ptr; ! 326: } ! 327: } ! 328: if ( vflag > 0) ! 329: fprintf(stderr, "failed to compute indx\n"); ! 330: exit(1); ! 331: } ! 332: ! 333: ! 334: /*eject*/ ! 335: ! 336: /* function "realindx" gives actual index of any "real" tag */ ! 337: ! 338: /* given that newloc != oldloc in our table, tag is C_ALIAS */ ! 339: ! 340: long ! 341: realindx(x) ! 342: ! 343: long x; ! 344: { ! 345: long i; ! 346: extern long tag_sum; ! 347: extern int vflag; ! 348: extern struct table *tbl_head; ! 349: ! 350: struct table *tbl_ptr; ! 351: ! 352: /* search table til x lies between 2 tag indexes */ ! 353: ! 354: tbl_ptr = tbl_head; ! 355: ! 356: for( i=0L; i<tag_sum; i++) { ! 357: if (x != tbl_ptr->oldlcn) { ! 358: if ( i != tag_sum-1 ) { ! 359: ++tbl_ptr; ! 360: } ! 361: } ! 362: else { ! 363: return(tbl_ptr->real_loc); ! 364: } ! 365: } ! 366: if ( vflag > 0) ! 367: fprintf(stderr, "failed to compute realindx at %ld\n", x); ! 368: exit(2); ! 369: } ! 370: ! 371: /*eject*/ ! 372: /* "prosym" processes entries in symbol table by actually deleting ! 373: * duplicate structures and modifying pointer information */ ! 374: ! 375: struct syment symbol; ! 376: union auxent auxil; ! 377: ! 378: extern char *str_table, *str_next; ! 379: ! 380: int ! 381: prosym(indx, nsyms, start) ! 382: ! 383: long indx, nsyms, start; ! 384: { ! 385: extern int vflag, ! 386: pflag; ! 387: extern long realindx(), ! 388: newindx(); ! 389: long nextin, thisin; ! 390: long duptag; ! 391: char *s; ! 392: long slength; ! 393: ! 394: /* verify that index is start of symbol table */ ! 395: ! 396: duptag = 0; ! 397: if ( indx != start) { ! 398: if ( vflag > 0) ! 399: fprintf(stderr, "error in symbol table indexing \n"); ! 400: return(FAILURE); ! 401: } ! 402: ! 403: /* read each entry and/or aux entry */ ! 404: ! 405: nextin = 0; ! 406: while (nextin < nsyms) { ! 407: thisin = nextin; ! 408: if ( ldtbread(oldfile, thisin, &symbol) == FAILURE) { ! 409: if ( vflag > 0) ! 410: fprintf(stderr, "unable to read symbol entry\n"); ! 411: return(ERROR); ! 412: } ! 413: #ifdef FLEXNAMES ! 414: if (symbol.n_zeroes == 0) /* put name in string table */ ! 415: { ! 416: extern char *keep_name(); ! 417: char *p; ! 418: ! 419: if ((p = keep_name(oldfile, &symbol)) == NULL) ! 420: return (ERROR); ! 421: symbol.n_offset = p - str_table; /* new offset */ ! 422: } ! 423: #endif ! 424: if ( symbol.n_numaux == 0) ! 425: nextin = thisin + 1; ! 426: else { ! 427: nextin=thisin + 2; ! 428: ! 429: /* read aux entry */ ! 430: ! 431: if ( fread(&auxil, AUXESZ, 1, IOPTR(oldfile))==FAILURE) { ! 432: if ( vflag > 0) ! 433: fprintf(stderr, "cannot read auxiliary entry\n"); ! 434: return(ERROR); ! 435: } ! 436: } ! 437: if ( symbol.n_numaux == 0) { ! 438: if ( symbol.n_sclass == C_ALIAS) { ! 439: symbol.n_value = realindx(symbol.n_value); ! 440: } ! 441: } ! 442: else { ! 443: switch (symbol.n_sclass) { ! 444: ! 445: case C_BLOCK: ! 446: s = symbol.n_name; ! 447: if (*s=='.' && *(++s)=='b' && *(++s)=='b') ! 448: auxil.x_sym.x_fcnary.x_fcn.x_endndx=newindx(auxil.x_sym.x_fcnary.x_fcn.x_endndx); ! 449: break; ! 450: ! 451: case C_ENTAG: ! 452: auxil.x_sym.x_fcnary.x_fcn.x_endndx = newindx(auxil.x_sym.x_fcnary.x_fcn.x_endndx); ! 453: auxil.x_sym.x_tagndx=newindx(auxil.x_sym.x_tagndx); ! 454: break; ! 455: ! 456: case C_EOS: ! 457: auxil.x_sym.x_tagndx=newindx(auxil.x_sym.x_tagndx); ! 458: break; ! 459: ! 460: case C_FILE: ! 461: symbol.n_value=newindx(symbol.n_value); ! 462: break; ! 463: ! 464: case C_STRTAG: ! 465: case C_UNTAG: ! 466: if ( tagindx(thisin)==C_ALIAS) { ! 467: nextin = auxil.x_sym.x_fcnary.x_fcn.x_endndx; ! 468: duptag++; ! 469: } else ! 470: auxil.x_sym.x_fcnary.x_fcn.x_endndx=newindx(auxil.x_sym.x_fcnary.x_fcn.x_endndx); ! 471: break; ! 472: ! 473: default: ! 474: if (ISFCN(symbol.n_type)) { ! 475: auxil.x_sym.x_fcnary.x_fcn.x_endndx=newindx(auxil.x_sym.x_fcnary.x_fcn.x_endndx); ! 476: } ! 477: ! 478: switch BTYPE(symbol.n_type) { ! 479: ! 480: case T_ENUM: ! 481: if (auxil.x_sym.x_tagndx == 0L) ! 482: break; ! 483: else ! 484: auxil.x_sym.x_tagndx = newindx(auxil.x_sym.x_tagndx); ! 485: break; ! 486: ! 487: case T_STRUCT: ! 488: case T_UNION: ! 489: if (auxil.x_sym.x_tagndx == 0L) ! 490: break; ! 491: else ! 492: auxil.x_sym.x_tagndx = realindx(auxil.x_sym.x_tagndx); ! 493: break; ! 494: } /* end of second switch */ ! 495: ! 496: break; ! 497: } /* end of main switch */ ! 498: } /* end of else */ ! 499: ! 500: if ( fwrite(&symbol, SYMESZ, 1, compress) != 1) { ! 501: if ( vflag > 0) ! 502: fprintf(stderr, "failed to write symbol\n"); ! 503: return(FAILURE); ! 504: } ! 505: if ( symbol.n_numaux == 1) ! 506: if ( fwrite(&auxil, AUXESZ, 1, compress) != 1) { ! 507: if ( vflag > 0) ! 508: fprintf(stderr, "failed to write aux\n"); ! 509: return(FAILURE); ! 510: } ! 511: } /* end of while loop */ ! 512: ! 513: #ifdef FLEXNAMES ! 514: /* ! 515: * Write out modified string table. Place string table length ! 516: * at beginning. Don't bother to check stuff at end of old file. ! 517: */ ! 518: slength = str_next - str_table; ! 519: if (slength > sizeof(long) / sizeof(char)) ! 520: { ! 521: str_table += sizeof(long) / sizeof(char); ! 522: if (fwrite((char *)&slength, sizeof(long), 1, compress) != 1 || ! 523: fwrite(str_table, sizeof(char), ! 524: slength - sizeof(long) / sizeof(char), compress) != ! 525: slength - sizeof(long) / sizeof(char)) ! 526: { ! 527: if (vflag > 0) ! 528: fprintf(stderr, ! 529: "failed to write string table\n"); ! 530: return (FAILURE); ! 531: } ! 532: } ! 533: #else ! 534: /* verify that no more entries exist */ ! 535: if ( ldtbread(oldfile, nextin, &symbol) != FAILURE) { ! 536: if ( vflag > 0) ! 537: fprintf(stderr, "error in count of symbols\n"); ! 538: exit(3); ! 539: } ! 540: #endif ! 541: if ( pflag > 0) ! 542: printf("total number of duplicate tags = %ld\n", duptag); ! 543: return(SUCCESS); ! 544: } ! 545: ! 546: ! 547: ! 548: /*eject*/ ! 549: ! 550: /* "tagindx" computes value for C_ALIAS entries */ ! 551: ! 552: ! 553: int ! 554: tagindx(symindx) ! 555: ! 556: long symindx; ! 557: { ! 558: extern long tag_sum; ! 559: extern struct table *tbl_head; ! 560: struct table *tbl_ptr; ! 561: long i; ! 562: ! 563: /* search tag table for oldloc of given tag indx */ ! 564: ! 565: tbl_ptr = tbl_head; ! 566: ! 567: for( i=0L; i < tag_sum; i++) { ! 568: if ( symindx == tbl_ptr->oldlcn) { ! 569: if ( tbl_ptr->newlcn != tbl_ptr->real_loc) { ! 570: symbol.n_sclass = C_ALIAS; ! 571: symbol.n_numaux = 0; ! 572: symbol.n_value = tbl_ptr->real_loc; ! 573: return(C_ALIAS); ! 574: } ! 575: return(0); ! 576: } ! 577: if ( i != tag_sum-1 ) { ! 578: ++tbl_ptr; ! 579: } ! 580: } ! 581: return(0); ! 582: } ! 583: ! 584: ! 585: /*eject*/ ! 586: int ! 587: copy(size) ! 588: ! 589: long size; ! 590: ! 591: { ! 592: extern int fread( ), ! 593: fwrite( ); ! 594: ! 595: extern FILE *compress; ! 596: extern LDFILE *oldfile; ! 597: ! 598: /* */ short buffer[BSIZE]; ! 599: long index; ! 600: /* */ short remaindr; ! 601: ! 602: ! 603: for (index = size/BSIZE; index > 0; --index) { ! 604: if (fread(buffer, BSIZE, 1, IOPTR(oldfile)) < 1) { ! 605: return(FAILURE); ! 606: } ! 607: ! 608: if (fwrite(buffer, BSIZE, 1, compress) != 1) { ! 609: return(FAILURE); ! 610: } ! 611: } ! 612: ! 613: if ((remaindr = size % BSIZE) != 0) { ! 614: if (fread(buffer, remaindr, 1, IOPTR(oldfile)) != 1) { ! 615: return(FAILURE); ! 616: } ! 617: ! 618: if (fwrite(buffer, remaindr, 1, compress) != 1) { ! 619: return(FAILURE); ! 620: } ! 621: } ! 622: ! 623: return(SUCCESS); ! 624: } ! 625: ! 626: #ifdef FLEXNAMES ! 627: reinit_strings() ! 628: { ! 629: register int i; ! 630: ! 631: str_next = str_table + (sizeof(long) / sizeof(char)); ! 632: for (i=0; i < sizeof(long) / sizeof(char); i++) ! 633: str_table[i] = '\0'; ! 634: } ! 635: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.