|
|
1.1 root 1: static char ID[] = "@(#) ld01.c: 1.13 8/18/83";
2: #include "system.h"
3: #include <stdio.h>
4: #include <signal.h>
5: #include "structs.h"
6: #include "extrns.h"
7:
8: #if !ONEPROC || TRVEC
9: #include "tv.h"
10: #include "ldtv.h"
11: #endif
12:
13: #include "list.h"
14: #include "sgsmacros.h"
15: #include "instr.h"
16: #include "ldmacros.h"
17:
18: #define STRINC 256
19: /*eject*/
20: #if ONEPROC
21: pass2()
22: #else
23: main(argc,argv)
24: int argc;
25: char *argv[];
26: #endif
27: {
28:
29: /*
30: * This is the MAIN procedure for PASS 2 of ld
31: *
32: * PASS 2 is the execution pass:
33: * 1. The control information extracted during PASS 1 is read in
34: * 2. Control blocks are constructed, containing the information
35: * extracted during PASS 1
36: * 3. Allocation is performed
37: * 4. The output file is generated
38: */
39:
40: /*
41: * Initialize PASS 2
42: */
43:
44: #if ONEPROC
45: initpss2();
46: #else
47: initpass2(argv[1]);
48: #endif
49:
50: /*
51: * If necessary, make the symbol "_start" undefined
52: */
53:
54: undefine();
55:
56:
57: /*
58: * Apply, if any, the default SECTIONS directives
59: */
60:
61: dfltsec();
62:
63: psymdef(); /* process symbol (un)definition */
64: pmemreg(); /* process memlist and reglist */
65: ploadfil(); /* process LDFILE list */
66: #if TRVEC
67: if (tvflag) /* look for references to functions */
68: tvreloc();
69: #endif
70: #if COMMON
71: if (aflag)
72: pf77comm(); /* process common data for F77 */
73: #endif
74: pboslist(); /* process BLDOUTSEC list */
75: split_scns(); /* break up outscts if they are too big */
76: alloc(); /* perform output section allocation */
77: if (Bflag)
78: add_pad(); /* add padding sections */
79: #if ILDOPT
80: if (ildflag) /* add extra sections */
81: add_extra();
82: #endif
83: updatsms(); /* complete section hdrs & relocate symbols */
84: pexlist(); /* process expression list */
85:
86:
87: /*
88: * Output a memory map if requested:
89: * 1. The -m flag was set
90: * 2. There were no .o or archive files in the ld run
91: */
92:
93: if( mflag )
94: ldmap();
95:
96: if (cflag != 3)
97: output(); /* write output object file */
98:
99: #if DEBUG
100: if (dflag)
101: fprintf( stderr, "total work space allocated: %d\n", allocspc );
102: #endif
103:
104: #if !NOSDP
105: symfini();
106: #endif
107:
108: instrment();
109:
110: exit(0);
111: }
112: /*eject*/
113: instrment()
114: {
115: register FILE *instrfile;
116: long times();
117:
118: /*
119: * Complete the collection of the timing statistics
120: */
121:
122: ttime = times(&ptimes) - ttime;
123:
124: /*
125: * Determine if any statistics are to be output
126: */
127:
128: if( (instrfile = fopen("instr.data", "r")) == NULL )
129: return;
130: else
131: fclose(instrfile);
132:
133: if( (instrfile = fopen("instr.data", "a")) == NULL ) {
134: lderror(0,0,NULL,"Can't open 'instr.data'");
135: return;
136: }
137:
138: /*
139: * Output the ld run statistics
140: */
141:
142: fprintf( instrfile, "%07ld %07ld %07ld %07ld\n",
143: SDP_read, SDP_write, LD_lock, LD_unlock);
144: fprintf( instrfile, "%07ld %07ld %07ld %07ld %07ld %07ld %07ld\n",
145: noutsyms, numldsyms, numldaux, nwalks, nfwalks, maxchain,
146: ncolisns );
147: fprintf( instrfile, "%07ld %07ld %07ld %07ld %07ld\n",
148: ttime, ptimes );
149: fprintf( instrfile, "%07ld %07ld\n",
150: allocspc, maxalloc);
151:
152: fclose(instrfile);
153: }
154: /*eject*/
155: #if ONEPROC
156: initpss2()
157: #else
158: initpass2(file)
159: char *file;
160: #endif
161: {
162:
163: long times();
164: int ldexit();
165:
166: /*
167: * Initialize the process time counters
168: */
169:
170: #if !ONEPROC
171: ttime = times(&ptimes);
172: #endif
173:
174:
175: /*
176: * Set the following signals to be caught, unless ld is running in the
177: * background. In this case, leave them set at "ignore"
178: */
179:
180: if( signal(SIGINT, ldexit) == SIG_IGN )
181: signal(SIGINT, SIG_IGN);
182: if( signal(SIGHUP, ldexit) == SIG_IGN )
183: signal(SIGHUP, SIG_IGN);
184: if( signal(SIGQUIT, ldexit) == SIG_IGN )
185: signal(SIGQUIT, SIG_IGN);
186:
187: /*
188: * Open the "transfer file" built during PASS 1
189: *
190: * Unless PASS 2 is being run manually,
191: * THIS FILE IS ALWAYS UNLINKED BY PASS 2
192: */
193:
194: #if !ONEPROC
195: if( (trnfdes = fopen(file,"r")) == NULL )
196: lderror(2,0,NULL, "Can't open internal file %s",
197: file );
198: #if AR16WR
199: trnfbuf = myalloc( BUFSIZ );
200: setbuf( trnfdes, trnfbuf );
201: #endif
202: #endif
203:
204: /*
205: * Initialize the Software Demand Paging System
206: */
207:
208: #if (!NOSDP) && (!ONEPROC)
209: syminit();
210: #endif
211:
212:
213: #if !ONEPROC
214: /*
215: * Input control and descriptor information
216: */
217:
218: fseek( trnfdes, 0L, 0 );
219:
220: /*
221: * Input the sizes of the lists built during PASS 1
222: *
223: * 1. define symbol directives
224: * 2. MEMORY directives
225: * 3. REGIONS directives
226: * 4. input *.o and archive library files
227: * 5. output sections
228: * 6. assignment directives
229: * 7. tv slot assignment directives
230: */
231:
232: fread( &symcnt, sizeof(int), 1, trnfdes );
233: fread( &memcnt, sizeof(int), 1, trnfdes );
234: fread( ®cnt, sizeof(int), 1, trnfdes );
235: fread( &ldfcnt, sizeof(int), 1, trnfdes );
236: fread( &bldcnt, sizeof(int), 1, trnfdes );
237: fread( &expcnt, sizeof(int), 1, trnfdes );
238: fread( &tvslotcnt, sizeof(int), 1, trnfdes );
239:
240: /*
241: * Input the ld control flags
242: */
243:
244: fread( &aflag, sizeof(char), 1, trnfdes );
245: fread( &cflag, sizeof(char), 1, trnfdes );
246: fread( &dflag, sizeof(char), 1, trnfdes );
247: fread( &iflag, sizeof(char), 1, trnfdes );
248: fread( &mflag, sizeof(char), 1, trnfdes );
249: fread( &rflag, sizeof(char), 1, trnfdes );
250: fread( &sflag, sizeof(char), 1, trnfdes );
251: fread( &tvflag, sizeof(char), 1, trnfdes );
252: fread( &Hflag, sizeof(char), 1, trnfdes );
253: fread( &Nflag, sizeof(char), 1, trnfdes );
254: fread( &Sflag, sizeof(char), 1, trnfdes );
255: fread( &Vflag, sizeof(char), 1, trnfdes );
256: fread( &Xflag, sizeof(char), 1, trnfdes );
257: fread( &hflag, sizeof(int), 1, trnfdes );
258: fread( &pflag, sizeof(int), 1, trnfdes );
259: fread( &Bflag, sizeof(int), 1, trnfdes );
260: fread( &VSflag, sizeof(short), 1, trnfdes );
261: #if UNIX || XL
262: fread( &xflag, sizeof(char), 1, trnfdes );
263: #endif
264: #if COMMON
265: fread( &tflag, sizeof(char), 1, trnfdes );
266: fread( &Mflag, sizeof(char), 1, trnfdes );
267: #endif
268: #if PAGING
269: fread( &Fflag, sizeof(char), 1, trnfdes );
270: #endif
271: #if PAGING
272: fread( &zflag, sizeof(char), 1, trnfdes );
273: #endif
274: #if ILDOPT
275: fread( &ildflag, sizeof(char), 1, trnfdes );
276: #endif
277:
278: /*
279: * Input various values extracted from the parse
280: */
281:
282: fread( &globfill, sizeof(short), 1, trnfdes );
283: fread( &magic, sizeof(unsigned short), 1, trnfdes );
284: fread( outfilnm, 128, 1, trnfdes );
285: fread( epsymbol, 8, 1, trnfdes );
286: fread( &tvspec, sizeof(TVINFO), 1, trnfdes );
287: fread( &strleng, sizeof(int), 1, trnfdes );
288:
289: #if DEBUG
290: if( dflag > 2 ) {
291: fprintf( stderr, "\nList sizes:\n\tSYM: %d MEM: %d REG: %d LDF : %d BLD: %d EXP : %d",
292: symcnt, memcnt, regcnt, ldfcnt, bldcnt, expcnt );
293: fprintf( stderr, "\nFlag values:\n\ta c d i m p r s tv H S V X h B" );
294: fprintf( stderr, "\n\t%d %d %d %d %d %d %d %d %d %d %d %d %d %04x %04x",
295: aflag,cflag,dflag,iflag,mflag,pflag,rflag,sflag,tvflag,
296: Hflag,Sflag,Vflag,Xflag,hflag,Bflag);
297: fprintf( stderr, "\nControl values:\n\tglobal fill: %04x magic: %04x a.out: (%.128s) ep: (%.8s)",
298: globfill, magic, outfilnm, epsymbol );
299: fprintf( stderr, "\n\ttv: %04x (%8.8s) (%08lx) (%04x) %d %d %08lx",
300: tvspec.tvosptr, tvspec.tvfnfill, tvspec.tvfill,
301: tvspec.tvinflnm, tvspec.tvinlnno,
302: tvspec.tvlength, tvspec.tvbndadr );
303: fprintf( stderr, "\nString area length: %d\n", strleng );
304: }
305: #endif
306:
307: /*
308: * Input the strings saved from PASS 1:
309: * The names of input ifiles, input *.o and archive files
310: *
311: * Allow for a small amount of additional growth, during PASS 2
312: */
313:
314: strbase = myalloc(strleng + STRINC);
315: fread( strbase, 1, strleng, trnfdes );
316:
317: strnext = strbase + strleng;
318: strlimit = strnext + STRINC;
319: #endif
320:
321: #if TRVEC
322: if (tvflag)
323: tvspecdef(); /* complete definition of tvspec */
324: #endif
325:
326: #if !ONEPROC
327: if( cflag != 2 )
328: unlink( file );
329: #endif
330: }
331: /*eject*/
332: ldexit()
333: {
334:
335: /*
336: * Clean up and exit after a fatal error
337: */
338:
339: signal(SIGINT, SIG_IGN);
340: signal(SIGQUIT, SIG_DFL);
341: signal(SIGTERM, SIG_IGN);
342: signal(SIGHUP, SIG_DFL);
343:
344: /*
345: * Unlink the a.out file, to cause its removal
346: */
347:
348: unlink( outfilnm );
349:
350: #if !NOSDP
351: symfini();
352:
353: svfini();
354: #endif
355:
356: exit(13); /* unlucky break */
357: }
358: /*eject*/
359: undefsm(name)
360: char *name;
361: {
362:
363: /*
364: * Create a symbol table entry for an undefined symbol
365: * ( which may get defined later).
366: */
367:
368: SYMENT sym;
369:
370: zero( (char *) &sym, SYMESZ );
371:
372: #if FLEXNAMES
373: if (strlen(name) > 8) {
374: sym.n_zeroes = 0L;
375: sym.n_nptr = name;
376: }
377: else
378: #endif
379: copy( sym.n_name, name, 8);
380: sym.n_sclass = C_EXT;
381:
382: putsym( makesym(&sym, NULL), 1 );
383: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.