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