|
|
1.1 ! root 1: /* $Header: /newbits/bin/ld/RCS/pass2.sav,v 1.1 91/05/15 09:44:51 bin Exp $ ! 2: * ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * Coherent Version 2.3.38 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: * ! 15: * Modifications Copyright INETCO Systems Ltd. ! 16: */ ! 17: /* ! 18: * Pass 2 ! 19: * Read, relocate and output segments of module ! 20: * ! 21: * $Log: /newbits/bin/ld/RCS/pass2.sav,v $ ! 22: * Revision 1.1 91/05/15 09:44:51 bin ! 23: * Initial revision ! 24: * ! 25: * Revision 1.1 89/07/21 15:52:26 src ! 26: * Initial revision ! 27: * ! 28: * 87/10/04 Allan Cornish /usr/src/cmd/ld/pass2.c ! 29: * Comments extended. ! 30: */ ! 31: ! 32: #include "data.h" ! 33: ! 34: void ! 35: loadmod( mp ) ! 36: mod_t * mp; ! 37: { ! 38: seg_t *isgp, *irsp, *osgp, *orsp; ! 39: sym_t *sp; ! 40: int opcode, relseg; ! 41: int segn; ! 42: uaddr_t addr, bias; ! 43: unsigned int symno; ! 44: FILE *ifp, *irfp, *ofp, *orfp; ! 45: static FILE *inputf[NLSEG]; ! 46: static char *fname = NULL; ! 47: ! 48: if ( watch ) ! 49: mpmsg( mp, "loading" ); ! 50: ! 51: for ( segn = 0; segn < NLSEG; segn++ ) { ! 52: ! 53: if ( (segn != L_REL) && (outputf[segn] == NULL) ) ! 54: continue; ! 55: ! 56: if ( fname != mp->fname ) { ! 57: ! 58: if ( fname != NULL ) ! 59: fclose( inputf[segn] ); ! 60: ! 61: if (( inputf[segn] = fopen(mp->fname, "r")) == NULL ) { ! 62: filemsg(mp->fname, "can't open (pass 2)"); ! 63: exit(1); ! 64: } ! 65: } ! 66: ! 67: fseek( inputf[segn], mp->seg[segn].daddr, 0 ); ! 68: ! 69: if ( watch && (mp->seg[segn].size != 0) ) ! 70: message("relocating seg#%d[%06lo]@%06lo to %06lo", ! 71: segn, (long)mp->seg[segn].size, ! 72: (long)mp->seg[segn].vbase, ! 73: (long)oseg[segn].vbase); ! 74: } ! 75: ! 76: fname = mp->fname; ! 77: irfp = inputf[L_REL]; ! 78: irsp = &mp->seg[L_REL]; ! 79: orfp = outputf[L_REL]; ! 80: orsp = &oseg[L_REL]; ! 81: ! 82: while ( (opcode = getbyte(irfp, irsp)) != EOF ) { ! 83: ! 84: addr = getaddr( irfp, irsp ); ! 85: ! 86: /* ! 87: * Find segment in which it address lies ! 88: */ ! 89: for (segn=0, isgp=&mp->seg[0]; segn < L_SYM; segn++, isgp++) { ! 90: if ( (addr >= isgp->vbase) ! 91: && (addr < isgp->vbase+isgp->size) ) ! 92: break; ! 93: } ! 94: ! 95: if ( (segn == L_BSSI) ! 96: || (segn == L_BSSD) ! 97: || (segn == L_SYM) ) { ! 98: mpmsg( mp, "bad relocation address %06lo", (long)addr); ! 99: continue; ! 100: } ! 101: ! 102: ifp = inputf[segn]; ! 103: ofp = outputf[segn]; ! 104: osgp = &oseg[segn]; ! 105: ! 106: /* ! 107: * Put unrelocated stuff ! 108: */ ! 109: while ( isgp->vbase < addr ) ! 110: putbyte( getbyte(ifp, isgp), ofp, osgp ); ! 111: ! 112: bias = 0; ! 113: ! 114: switch ( relseg = (opcode & LR_SEG) ) { ! 115: ! 116: case L_SYM: ! 117: /* ! 118: * Symbolic reference: ! 119: * L_SYM[+LR_PCR+LR_WORD],addr-16,symno-16,offset ! 120: */ ! 121: symno = getsymno( irfp, irsp ); ! 122: ! 123: if ( symno >= mp->nsym ) { ! 124: mpmsg( mp, "bad reloc. sym. no. %d", symno ); ! 125: } ! 126: ! 127: else if ( (sp = mp->sym[symno]) == NULL ) { ! 128: mpmsg( mp, "symbol %d not kept", symno ); ! 129: } ! 130: ! 131: /* ! 132: * Symbolic reference not resolved. ! 133: */ ! 134: else if ( sp->s.ls_type == (L_GLOBAL|L_REF) ) { ! 135: if ( orfp != NULL ) { ! 136: putbyte( opcode, orfp, orsp ); ! 137: putaddr( osgp->vbase, orfp, orsp ); ! 138: putsymno( sp->symno, orfp, orsp ); ! 139: } ! 140: } ! 141: ! 142: /* ! 143: * Convert symbolic reference to segment reference. ! 144: */ ! 145: else { ! 146: bias = sp->s.ls_addr; ! 147: ! 148: if ( orfp != NULL ) { ! 149: putbyte(sp->s.ls_type&LR_SEG ! 150: |opcode&~LR_SEG, ! 151: orfp, orsp); ! 152: putaddr( osgp->vbase, orfp, orsp ); ! 153: ! 154: /* ! 155: * Keep segment size correct ! 156: */ ! 157: orsp->size -= sizeof(short); ! 158: } ! 159: } ! 160: break; ! 161: ! 162: case L_SHRI: ! 163: case L_PRVI: ! 164: case L_BSSI: ! 165: case L_SHRD: ! 166: case L_PRVD: ! 167: case L_BSSD: ! 168: bias = oseg[relseg].vbase ! 169: - mp->seg[relseg].vbase; ! 170: /* no break */ ! 171: ! 172: case L_ABS: ! 173: if ( orfp != NULL ) { ! 174: putbyte( opcode, orfp, orsp ); ! 175: putaddr( osgp->vbase, orfp, orsp ); ! 176: } ! 177: break; ! 178: ! 179: default: ! 180: goto BadCode; ! 181: } ! 182: ! 183: if ( opcode & LR_PCR ) ! 184: bias += isgp->vbase - osgp->vbase; ! 185: ! 186: switch ( opcode & LR_OP ) { ! 187: ! 188: default: ! 189: BadCode: ! 190: mpmsg( mp, "bad relocation opcode %03o", opcode ); ! 191: break; ! 192: ! 193: case LR_BYTE: ! 194: bias += getbyte( ifp, isgp ); ! 195: putbyte( (char)bias, ofp, osgp ); ! 196: break; ! 197: ! 198: case LR_WORD: ! 199: bias += getword( ifp, isgp ); ! 200: putword( (short)bias, ofp, osgp ); ! 201: break; ! 202: } ! 203: } ! 204: ! 205: /* ! 206: * Copy remainder of segments ! 207: */ ! 208: for ( segn = 0; segn < L_SYM; segn++ ) { ! 209: register int b; ! 210: ! 211: if ( (ofp = outputf[segn]) == NULL ) ! 212: continue; ! 213: ! 214: ifp = inputf[segn]; ! 215: isgp = &mp->seg[segn]; ! 216: osgp = &oseg[segn]; ! 217: ! 218: while ( (b = getbyte( ifp, isgp )) != EOF ) ! 219: putbyte( b, ofp, osgp ); ! 220: } ! 221: ! 222: /* ! 223: * Adjust bss bases (others done by putbyte) ! 224: */ ! 225: oseg[L_BSSD].vbase += mp->seg[L_BSSD].size; ! 226: oseg[L_BSSI].vbase += mp->seg[L_BSSI].size; ! 227: } ! 228: ! 229: /* ! 230: * I/O routines ! 231: */ ! 232: void ! 233: putstruc( p, s, fp, sgp ) ! 234: register char *p; ! 235: register unsigned int s; ! 236: register FILE *fp; ! 237: register seg_t *sgp; ! 238: { ! 239: while ( s-- ) ! 240: putbyte( *p++, fp, sgp ); ! 241: } ! 242: ! 243: unsigned short ! 244: getword( fp, sgp ) ! 245: FILE *fp; ! 246: seg_t *sgp; ! 247: { ! 248: return( (worder == LOHI) ? getlohi(fp,sgp) : gethilo(fp,sgp) ); ! 249: } ! 250: ! 251: unsigned short ! 252: getlohi( fp, sgp ) ! 253: FILE *fp; ! 254: seg_t *sgp; ! 255: { ! 256: register unsigned char b; ! 257: ! 258: b = getbyte( fp, sgp ); ! 259: return( (getbyte(fp,sgp) << 8) | b ); ! 260: } ! 261: ! 262: unsigned short ! 263: gethilo( fp, sgp ) ! 264: FILE *fp; ! 265: seg_t *sgp; ! 266: { ! 267: register unsigned char b; ! 268: ! 269: b = getbyte(fp, sgp); ! 270: return( (b << 8) | getbyte(fp,sgp) ); ! 271: } ! 272: ! 273: int ! 274: getbyte( fp, sgp ) ! 275: FILE *fp; ! 276: seg_t *sgp; ! 277: { ! 278: if ( sgp->size == 0 ) ! 279: return( EOF ); ! 280: ! 281: else { ! 282: sgp->size--; ! 283: sgp->vbase++; ! 284: return( getc(fp) ); ! 285: } ! 286: } ! 287: ! 288: void ! 289: putword( w, fp, sgp ) ! 290: unsigned short w; ! 291: FILE *fp; ! 292: seg_t *sgp; ! 293: { ! 294: if ( worder == LOHI ) ! 295: putlohi( w, fp, sgp ); ! 296: ! 297: else ! 298: puthilo( w, fp, sgp ); ! 299: } ! 300: ! 301: void ! 302: putlohi( w, fp, sgp ) ! 303: unsigned short w; ! 304: FILE *fp; ! 305: seg_t *sgp; ! 306: { ! 307: putbyte( w & 0377, fp, sgp ); ! 308: putbyte( w >>8, fp, sgp ); ! 309: } ! 310: ! 311: void ! 312: puthilo( w, fp, sgp ) ! 313: unsigned short w; ! 314: FILE *fp; ! 315: seg_t *sgp; ! 316: { ! 317: putbyte( w >> 8, fp, sgp ); ! 318: putbyte( w & 0377, fp, sgp ); ! 319: } ! 320: ! 321: void ! 322: putbyte( b, fp, sgp ) ! 323: unsigned char b; ! 324: FILE *fp; ! 325: seg_t *sgp; ! 326: { ! 327: sgp->vbase++; ! 328: putc( b, fp ); ! 329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.