|
|
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.