|
|
1.1 root 1: static char ID[] = "@(#) special2.c: 1.12 9/23/83";
2:
3: #include <stdio.h>
4:
5: #include "system.h"
6: #include "aouthdr.h"
7: #include "structs.h"
8: #include "ldfcn.h"
9: #include "tv.h"
10: #include "slotvec.h"
11: #include "reloc.h"
12: #include "extrns.h"
13: #include "sgsmacros.h"
14: #include "list.h"
15: #include "sgs.h"
16:
17: void
18: adjneed(need, osp, sap)
19:
20: ADDRESS *need;
21: OUTSECT *osp;
22: ANODE *sap;
23: {
24: /*
25: * adjust amount of memory allocated for a particular
26: * section; special processing step now used only
27: * for DMERT with TRVEC
28: */
29: }
30:
31: void
32: undefine()
33: {
34: /*
35: * for m32 version of ld01.c, the symbol "_start" does not
36: * need to be undefined
37: */
38: }
39:
40: void
41: dfltsec()
42: {
43: /*
44: * For the m32, the default action of nm32ld is to generate two m32
45: * segments: one for the text and the other for the data (both
46: * .data and .bss)
47: */
48:
49: ADDRESS lint = 0x80000;
50: ADDRESS *lptr = &lint;
51: ACTITEM *aiptr, *grptr;
52:
53: /*
54: * If any SECTIONS directives have been input, they take priority,
55: * and no default action is taken
56: */
57:
58: #if ONEPROC
59: if( bldoutsc.head )
60: #else
61: if( bldcnt)
62: #endif
63: return;
64:
65: #if PAGING
66: bond_t_d = 1; /* setting bond_t_d will tell pboslist to bind text
67: and data to the needed addresses */
68: #endif
69:
70: /*
71: * Generate a series of action itmes, as if the following had been
72: * input to m32ld:
73: *
74: * SECTIONS {
75: * .text : {}
76: * GROUP ALIGN(0x80000) : {
77: * .data : {}
78: * .bss : {}
79: * }
80: *
81: *
82: * Steps:
83: * 1. Define background variables
84: * 2. Process the .text definition
85: * 3. Process the GROUP definition
86: * 4. Process the .data definition
87: * 5. Process the .bss definition
88: *
89: *
90: * The logic used was obtained by simulating the action of the parser.
91: */
92:
93: memorg = 0x80800000L;
94: curfilnm = "*m32.default.file*";
95:
96: lineno = 2;
97: aiptr = dfnscngrp( AIDFNSCN, NULL, NULL, NULL );
98: aiptr->dfnscn.aisctype = STYP_REG;
99: copy( aiptr->dfnscn.ainame, _TEXT, 8 );
100: aiptr->dfnscn.aifill = 0;
101: aiptr->dfnscn.aifillfg = 0;
102: listadd( l_AI, &bldoutsc, aiptr );
103:
104: lineno = 3;
105: grptr = dfnscngrp( AIDFNGRP, NULL, lptr, NULL );
106: copy( grptr->dfnscn.ainame, "*group*", 7);
107:
108: lineno = 4;
109: aiptr = dfnscngrp( AIDFNSCN, NULL, NULL, NULL );
110: aiptr->dfnscn.aisctype = STYP_REG;
111: copy( aiptr->dfnscn.ainame, _DATA, 8 );
112: aiptr->dfnscn.aifill = 0;
113: aiptr->dfnscn.aifillfg = 0;
114: listadd( l_AI, &grptr->dfnscn.sectspec, aiptr );
115:
116: lineno = 5;
117: aiptr = dfnscngrp( AIDFNSCN, NULL, NULL, NULL );
118: aiptr->dfnscn.aisctype = STYP_REG;
119: copy( aiptr->dfnscn.ainame, _BSS, 8 );
120: aiptr->dfnscn.aifill = 0;
121: aiptr->dfnscn.aifillfg = 0;
122: listadd( l_AI, &grptr->dfnscn.sectspec, aiptr );
123:
124: listadd( l_AI, &bldoutsc, grptr );
125:
126: return;
127: }
128:
129: void
130: procspecobj(fdes, ap)
131: LDFILE *fdes;
132: ACTITEM *ap;
133: {
134: /*
135: * No more additional files to check
136: */
137:
138: lderror(1, ap->ldlbry.aiinlnno, ap->ldlbry.aiinflnm,
139: "file %s is of unknown type: magic number = %06.1x",
140: ap->ldlbry.aifilnam, TYPE(fdes));
141: }
142:
143: void
144: adjsize(osp)
145: OUTSECT *osp;
146: {
147: /*
148: * No special cases, no need to adjust size of output section
149: */
150: }
151:
152: void
153: adjaout(aout)
154: AOUTHDR *aout;
155: {
156: /*
157: * Indicate, via the MAGIC NUMBER, when the data segment starts
158: * on a m32 segment (512K bytes) boundary
159: */
160:
161: if( (aout->data_start & 0x7ffffL) == 0 )
162: aout->magic = (short) AOUT2MAGIC;
163: }
164:
165: void
166: relocate(ifd, rfd, infl, isp, osp, fdes, rdes, paddiff, relocfg, buf)
167: LDFILE *ifd, *rfd;
168: INFILE *infl;
169: INSECT *isp;
170: OUTSECT *osp;
171: FILE *fdes, *rdes;
172: long *paddiff;
173: register int *relocfg;
174: char *buf;
175: {
176: /*
177: * Process the section
178: */
179:
180: int numbytes;
181: long highaddr, vaddiff;
182: register long rdif, ndx;
183: union {
184: long l;
185: unsigned short u[2];
186: short i[2];
187: char c[4];
188: } value;
189: RELOC rentry;
190: register SLOTVEC *svp;
191:
192: #if RBO
193: /*
194: * for reverse byte ordering, two longs must be read in at a time,
195: * as the field may span a word boundary, and the bytes will no longer
196: * be contiguous.
197: */
198: union {
199: long l[2];
200: char c[8];
201: } rbobuf;
202: short buffered, pos, i;
203: long nextbnd;
204: #endif
205:
206: highaddr = isp->ishdr.s_vaddr + isp->ishdr.s_size;
207: vaddiff = isp->isnewvad - isp->ishdr.s_vaddr;
208: *paddiff = isp->isnewpad - isp->ishdr.s_paddr;
209: #if RBO
210: buffered = 0;
211: #endif
212:
213: for( ndx = isp->ishdr.s_vaddr; ndx < highaddr; ) {
214:
215: /*
216: * Read a relocation entry, if any left, and
217: * determine the size of the relocation field, in bytes
218: */
219: if( *relocfg ) {
220: if (fread(&rentry, RELSZ, 1, IOPTR(rfd)) != 1)
221: lderror(2,0,NULL,"fail to read the reloc entries of section %.8s of %s",
222: isp->ishdr.s_name,infl->flname);
223: (*relocfg)--;
224: switch (rentry.r_type) {
225:
226: case R_ABS:
227: /*
228: * No relocation, so skip to the
229: * next entry
230: */
231: if( rflag )
232: if( (svp = svread(rentry.r_symndx)) == NULL ) {
233: lderror(1,0,NULL, "reloc entry (%10.1lx, %ld %d) found for non-relocatable symbol, in section %.8s of file %s",
234: rentry, isp->ishdr.s_name, infl->flname);
235: goto nextentry;
236: }
237: else
238: goto nullentry;
239: goto nextentry;
240:
241:
242:
243: case R_DIR32:
244: case R_DIR32S:
245: break;
246:
247:
248: default:
249: lderror(2,0,NULL,
250: "Illegal relocation type %d found in section %.8s in file %s",
251: rentry.r_type, isp->ishdr.s_name, infl->flname);
252: }
253: }
254: /*
255: * There are no (more) relocation entries, so
256: * copy the rest of the section
257: */
258: else {
259: #if RBO
260: /*
261: * write out the contents of the reverse byte order
262: * buffer if necessary
263: */
264: if (buffered) {
265: buffered = 0;
266: fwrite( &rbobuf.l[1], sizeof(long), 1, fdes);
267: ndx += 4;
268: }
269: #endif
270: while( (rdif = highaddr - ndx) > 0 ) {
271: rdif = min(BUFSIZ, rdif);
272: if (FREAD(buf,(int) rdif,1,ifd) != 1 ||
273: fwrite(buf,(int) rdif,1,fdes) != 1)
274: lderror(2,0,NULL,"fail to copy the rest of section %.8s of file %s",
275: isp->ishdr.s_name,infl->flname);
276: ndx += rdif;
277: }
278: continue;
279: }
280:
281: /*
282: * Copy bytes that need no relocation
283: */
284: #if RBO
285: pos = rentry.r_vaddr % 4;
286: nextbnd = rentry.r_vaddr - pos;
287: if ( ((nextbnd - ndx) > 0) && buffered) {
288: buffered = 0;
289: fwrite( &rbobuf.l[1], sizeof(long), 1, fdes );
290: ndx += 4;
291: }
292:
293: while ((rdif = nextbnd - ndx) > 0) {
294: #else
295: while( (rdif = rentry.r_vaddr - ndx) > 0 ) {
296: #endif
297: rdif = min(BUFSIZ, rdif);
298: if (FREAD(buf,(int) rdif,1,ifd) != 1 ||
299: fwrite(buf,(int) rdif,1,fdes) != 1)
300: lderror(2,0,NULL,"fail to copy the bytes that need no reloc of section %.8s of file %s",
301: isp->ishdr.s_name,infl->flname);
302: ndx += rdif;
303: }
304:
305: if( rdif < 0 ) {
306: lderror(2,0,NULL, "Reloc entries out of order in section %.8s of file %s",
307: isp->ishdr.s_name, infl->flname);
308: }
309:
310: if( (svp = svread(rentry.r_symndx)) == NULL ) {
311: lderror(1,0,NULL, "No reloc entry found for symbol: index %ld, section %.8s, file %s",
312: rentry.r_symndx, isp->ishdr.s_name, infl->flname);
313: goto nextentry;
314: }
315:
316: rdif = svp->svnvaddr - svp->svovaddr;
317:
318: /*
319: * Special processing for COPY sections:
320: * do not touch the raw data (no relocation)
321: * but process relocation entries and lineno
322: * entries as usual
323: */
324:
325: if ( osp->oshdr.s_flags & STYP_COPY )
326: goto nullentry;
327:
328: switch( rentry.r_type ) {
329:
330: case R_DIR32:
331: if (FREAD( &value.l, sizeof(long), 1, ifd) != 1)
332: lderror( 2,0,NULL, "fail to read the field to be relocated in section %.8s, file %s",
333: isp->ishdr.s_name, infl->flname);
334: value.l = swapb4( swapb4( value.l, 0 ) + rdif, 0);
335: fwrite( &value.l, sizeof(long), 1, fdes );
336: ndx += 4;
337: break;
338:
339: case R_DIR32S:
340: #if RBO
341: if ( !buffered )
342: if (FREAD( &rbobuf.l[1], sizeof(long), 1, ifd ) != 1)
343: lderror( 2,0,NULL, "fail to read the field to be relocated in section %.8s, file %s",
344: isp->ishdr.s_name, infl->flname);
345: if (FREAD( &rbobuf.l[0], sizeof(long), 1, ifd ) != 1)
346: lderror( 2,0,NULL, "fail to read the field to be relocated in section %.8s, file %s",
347: isp->ishdr.s_name, infl->flname);
348: for ( i = 0; i <= 3; i ++ )
349: value.c[i] = rbobuf.c[7 - (pos + i)];
350: #else
351: if (FREAD( &value.l, sizeof(long), 1, ifd) != 1)
352: lderror( 2,0,NULL, "fail to read the field to be relocated in section %.8s, file %s",
353: isp->ishdr.s_name, infl->flname);
354: #endif
355:
356: value.l = swapb4( swapb4(value.l, 1) + rdif, 1 );
357:
358: #if RBO
359: for ( i = 0; i <= 3; i++ )
360: rbobuf.c[7 - (pos + i)] = value.c[i];
361: fwrite( &rbobuf.l[1], sizeof(long), 1, fdes );
362: rbobuf.l[1] = rbobuf.l[0];
363: buffered = 1;
364: #else
365: fwrite( &value.l, sizeof(long), 1, fdes );
366: #endif
367: ndx += 4;
368: break;
369: }
370:
371: nullentry: /*
372: * Preserve relocation entries
373: */
374: if( rflag ) {
375: rentry.r_vaddr += vaddiff;
376: rentry.r_symndx = svp->svnewndx;
377: fwrite(&rentry, RELSZ, 1, rdes);
378: }
379:
380: nextentry: ;
381: }
382:
383: }
384:
385: long
386: swapb4(val, type)
387: long val;
388: int type;
389: {
390: register long result;
391:
392:
393: /*
394: * Reorder the bytes of a long, converting to/from UNIX/M32 format
395: *
396: * val : w x y z
397: *
398: * 11/70 :0: xwzy
399: * :1: yzwx
400: * vax :0: zyxw
401: * :1: no change
402: *
403: * other :0: no change
404: * :1: zyxw
405: */
406:
407: if( type ) {
408: #if AR16WR || AR32W
409: result = (val >> 16) & 0x0000FFFFL;
410: result |= (val << 16) & 0xFFFF0000L;
411: #if AR32W
412: val = result;
413: result = (val >> 8) & 0x00FF00FFL;
414: result |= (val << 8) & 0xFF00FF00L;
415: #endif
416: #else
417: result = val;
418: #endif
419: }
420: else {
421: #if AR16WR || AR32WR
422: result = (val >> 8) & 0x00FF00FFL;
423: result |= (val << 8) & 0xFF00FF00L;
424: #if AR32WR
425: val = result;
426: result = (val >> 16) & 0x0000FFFFL;
427: result |=(val << 16) & 0xFFFF0000L;
428: #endif
429: #else
430: result = val;
431: #endif
432: }
433:
434: return( result );
435:
436: }
437:
438: void
439: procext(tvndx, secnum, sltval1, sltval2, ovaddr, nvaddr, gsp, sm)
440: int *tvndx, secnum;
441: long *sltval1, *sltval2, *ovaddr, *nvaddr;
442: register SYMTAB *gsp;
443: register SYMENT *sm;
444: {
445: if( secnum > 0 ) {
446: *sltval1 = ovaddr[secnum];
447: *sltval2 = nvaddr[secnum];
448: }
449: else {
450: *sltval1 = sm->n_value;
451: *sltval2 = gsp->smnewvirt;
452: }
453: }
454:
455: void
456: proclocstat(sm, infd, segment, newscnum, tvndx, ovaddr, nvaddr, opaddr, npaddr, ndx, sltval1, sltval2, count)
457: register SYMENT *sm;
458: LDFILE *infd;
459: int *segment, *newscnum, *tvndx;
460: long *ovaddr, *nvaddr, *opaddr, *npaddr, ndx, *sltval1, *sltval2, count;
461: {
462:
463: *sltval1 = ovaddr[sm->n_scnum];
464: *sltval2 = nvaddr[sm->n_scnum];
465: svcreate(count, *sltval1, *sltval2, ndx, newscnum[sm->n_scnum],
466: 0);
467:
468: }
469:
470: void
471: setslot(pglob, psect, outslot)
472: SYMTAB *pglob;
473: SCNHDR *psect;
474: TVENTRY *outslot;
475: {
476: /*
477: * no user defined transfer vector slot in tv.c for m32
478: */
479: }
480:
481: void
482: slotassign(tvent, pglob)
483: TVENTRY *tvent;
484: SYMTAB *pglob;
485: {
486: long paddr;
487:
488: paddr = pglob->smnewval;
489:
490: /*
491: * do not need to assign value to transfer vector
492: * entry for global symbol in tv.c for m32
493: */
494: }
495:
496: void
497: settventry(tvent, psym)
498: TVENTRY *tvent;
499: struct syment *psym;
500: {
501: /*
502: * no values to assign to transfer vector entry for local
503: * symbol in tv.c for m32
504: */
505: }
506:
507: void
508: filltvassign(psym)
509: SYMTAB *psym;
510: {
511: /*
512: * no fill values to assign for transfer vector in tv.c for m32
513: */
514: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.