|
|
researchv9-SUN3(old)
static char ID[] = "@(#) ld01.c: 1.13 8/18/83";
#include "system.h"
#include <stdio.h>
#include <signal.h>
#include "structs.h"
#include "extrns.h"
#if !ONEPROC || TRVEC
#include "tv.h"
#include "ldtv.h"
#endif
#include "list.h"
#include "sgsmacros.h"
#include "instr.h"
#include "ldmacros.h"
#define STRINC 256
/*eject*/
#if ONEPROC
pass2()
#else
main(argc,argv)
int argc;
char *argv[];
#endif
{
/*
* This is the MAIN procedure for PASS 2 of ld
*
* PASS 2 is the execution pass:
* 1. The control information extracted during PASS 1 is read in
* 2. Control blocks are constructed, containing the information
* extracted during PASS 1
* 3. Allocation is performed
* 4. The output file is generated
*/
/*
* Initialize PASS 2
*/
#if ONEPROC
initpss2();
#else
initpass2(argv[1]);
#endif
/*
* If necessary, make the symbol "_start" undefined
*/
undefine();
/*
* Apply, if any, the default SECTIONS directives
*/
dfltsec();
psymdef(); /* process symbol (un)definition */
pmemreg(); /* process memlist and reglist */
ploadfil(); /* process LDFILE list */
#if TRVEC
if (tvflag) /* look for references to functions */
tvreloc();
#endif
#if COMMON
if (aflag)
pf77comm(); /* process common data for F77 */
#endif
pboslist(); /* process BLDOUTSEC list */
split_scns(); /* break up outscts if they are too big */
alloc(); /* perform output section allocation */
if (Bflag)
add_pad(); /* add padding sections */
#if ILDOPT
if (ildflag) /* add extra sections */
add_extra();
#endif
updatsms(); /* complete section hdrs & relocate symbols */
pexlist(); /* process expression list */
/*
* Output a memory map if requested:
* 1. The -m flag was set
* 2. There were no .o or archive files in the ld run
*/
if( mflag )
ldmap();
if (cflag != 3)
output(); /* write output object file */
#if DEBUG
if (dflag)
fprintf( stderr, "total work space allocated: %d\n", allocspc );
#endif
#if !NOSDP
symfini();
#endif
instrment();
exit(0);
}
/*eject*/
instrment()
{
register FILE *instrfile;
long times();
/*
* Complete the collection of the timing statistics
*/
ttime = times(&ptimes) - ttime;
/*
* Determine if any statistics are to be output
*/
if( (instrfile = fopen("instr.data", "r")) == NULL )
return;
else
fclose(instrfile);
if( (instrfile = fopen("instr.data", "a")) == NULL ) {
lderror(0,0,NULL,"Can't open 'instr.data'");
return;
}
/*
* Output the ld run statistics
*/
fprintf( instrfile, "%07ld %07ld %07ld %07ld\n",
SDP_read, SDP_write, LD_lock, LD_unlock);
fprintf( instrfile, "%07ld %07ld %07ld %07ld %07ld %07ld %07ld\n",
noutsyms, numldsyms, numldaux, nwalks, nfwalks, maxchain,
ncolisns );
fprintf( instrfile, "%07ld %07ld %07ld %07ld %07ld\n",
ttime, ptimes );
fprintf( instrfile, "%07ld %07ld\n",
allocspc, maxalloc);
fclose(instrfile);
}
/*eject*/
#if ONEPROC
initpss2()
#else
initpass2(file)
char *file;
#endif
{
long times();
int ldexit();
/*
* Initialize the process time counters
*/
#if !ONEPROC
ttime = times(&ptimes);
#endif
/*
* Set the following signals to be caught, unless ld is running in the
* background. In this case, leave them set at "ignore"
*/
if( signal(SIGINT, ldexit) == SIG_IGN )
signal(SIGINT, SIG_IGN);
if( signal(SIGHUP, ldexit) == SIG_IGN )
signal(SIGHUP, SIG_IGN);
if( signal(SIGQUIT, ldexit) == SIG_IGN )
signal(SIGQUIT, SIG_IGN);
/*
* Open the "transfer file" built during PASS 1
*
* Unless PASS 2 is being run manually,
* THIS FILE IS ALWAYS UNLINKED BY PASS 2
*/
#if !ONEPROC
if( (trnfdes = fopen(file,"r")) == NULL )
lderror(2,0,NULL, "Can't open internal file %s",
file );
#if AR16WR
trnfbuf = myalloc( BUFSIZ );
setbuf( trnfdes, trnfbuf );
#endif
#endif
/*
* Initialize the Software Demand Paging System
*/
#if (!NOSDP) && (!ONEPROC)
syminit();
#endif
#if !ONEPROC
/*
* Input control and descriptor information
*/
fseek( trnfdes, 0L, 0 );
/*
* Input the sizes of the lists built during PASS 1
*
* 1. define symbol directives
* 2. MEMORY directives
* 3. REGIONS directives
* 4. input *.o and archive library files
* 5. output sections
* 6. assignment directives
* 7. tv slot assignment directives
*/
fread( &symcnt, sizeof(int), 1, trnfdes );
fread( &memcnt, sizeof(int), 1, trnfdes );
fread( ®cnt, sizeof(int), 1, trnfdes );
fread( &ldfcnt, sizeof(int), 1, trnfdes );
fread( &bldcnt, sizeof(int), 1, trnfdes );
fread( &expcnt, sizeof(int), 1, trnfdes );
fread( &tvslotcnt, sizeof(int), 1, trnfdes );
/*
* Input the ld control flags
*/
fread( &aflag, sizeof(char), 1, trnfdes );
fread( &cflag, sizeof(char), 1, trnfdes );
fread( &dflag, sizeof(char), 1, trnfdes );
fread( &iflag, sizeof(char), 1, trnfdes );
fread( &mflag, sizeof(char), 1, trnfdes );
fread( &rflag, sizeof(char), 1, trnfdes );
fread( &sflag, sizeof(char), 1, trnfdes );
fread( &tvflag, sizeof(char), 1, trnfdes );
fread( &Hflag, sizeof(char), 1, trnfdes );
fread( &Nflag, sizeof(char), 1, trnfdes );
fread( &Sflag, sizeof(char), 1, trnfdes );
fread( &Vflag, sizeof(char), 1, trnfdes );
fread( &Xflag, sizeof(char), 1, trnfdes );
fread( &hflag, sizeof(int), 1, trnfdes );
fread( &pflag, sizeof(int), 1, trnfdes );
fread( &Bflag, sizeof(int), 1, trnfdes );
fread( &VSflag, sizeof(short), 1, trnfdes );
#if UNIX || XL
fread( &xflag, sizeof(char), 1, trnfdes );
#endif
#if COMMON
fread( &tflag, sizeof(char), 1, trnfdes );
fread( &Mflag, sizeof(char), 1, trnfdes );
#endif
#if PAGING
fread( &Fflag, sizeof(char), 1, trnfdes );
#endif
#if PAGING
fread( &zflag, sizeof(char), 1, trnfdes );
#endif
#if ILDOPT
fread( &ildflag, sizeof(char), 1, trnfdes );
#endif
/*
* Input various values extracted from the parse
*/
fread( &globfill, sizeof(short), 1, trnfdes );
fread( &magic, sizeof(unsigned short), 1, trnfdes );
fread( outfilnm, 128, 1, trnfdes );
fread( epsymbol, 8, 1, trnfdes );
fread( &tvspec, sizeof(TVINFO), 1, trnfdes );
fread( &strleng, sizeof(int), 1, trnfdes );
#if DEBUG
if( dflag > 2 ) {
fprintf( stderr, "\nList sizes:\n\tSYM: %d MEM: %d REG: %d LDF : %d BLD: %d EXP : %d",
symcnt, memcnt, regcnt, ldfcnt, bldcnt, expcnt );
fprintf( stderr, "\nFlag values:\n\ta c d i m p r s tv H S V X h B" );
fprintf( stderr, "\n\t%d %d %d %d %d %d %d %d %d %d %d %d %d %04x %04x",
aflag,cflag,dflag,iflag,mflag,pflag,rflag,sflag,tvflag,
Hflag,Sflag,Vflag,Xflag,hflag,Bflag);
fprintf( stderr, "\nControl values:\n\tglobal fill: %04x magic: %04x a.out: (%.128s) ep: (%.8s)",
globfill, magic, outfilnm, epsymbol );
fprintf( stderr, "\n\ttv: %04x (%8.8s) (%08lx) (%04x) %d %d %08lx",
tvspec.tvosptr, tvspec.tvfnfill, tvspec.tvfill,
tvspec.tvinflnm, tvspec.tvinlnno,
tvspec.tvlength, tvspec.tvbndadr );
fprintf( stderr, "\nString area length: %d\n", strleng );
}
#endif
/*
* Input the strings saved from PASS 1:
* The names of input ifiles, input *.o and archive files
*
* Allow for a small amount of additional growth, during PASS 2
*/
strbase = myalloc(strleng + STRINC);
fread( strbase, 1, strleng, trnfdes );
strnext = strbase + strleng;
strlimit = strnext + STRINC;
#endif
#if TRVEC
if (tvflag)
tvspecdef(); /* complete definition of tvspec */
#endif
#if !ONEPROC
if( cflag != 2 )
unlink( file );
#endif
}
/*eject*/
ldexit()
{
/*
* Clean up and exit after a fatal error
*/
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_IGN);
signal(SIGHUP, SIG_DFL);
/*
* Unlink the a.out file, to cause its removal
*/
unlink( outfilnm );
#if !NOSDP
symfini();
svfini();
#endif
exit(13); /* unlucky break */
}
/*eject*/
undefsm(name)
char *name;
{
/*
* Create a symbol table entry for an undefined symbol
* ( which may get defined later).
*/
SYMENT sym;
zero( (char *) &sym, SYMESZ );
#if FLEXNAMES
if (strlen(name) > 8) {
sym.n_zeroes = 0L;
sym.n_nptr = name;
}
else
#endif
copy( sym.n_name, name, 8);
sym.n_sclass = C_EXT;
putsym( makesym(&sym, NULL), 1 );
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.