USG_PG3/usr/source/lil/pass2c.c
#define BUFSIZE 512
#define BUFEND 256
#define SYMSIZE 12
#define BINSIZE 6
#define EXTERN 040
#define ABSLOAD 0
#define BRANCH 1
#define JUMP 2
#define LOADELC 3
#define CBITS 0666
#define EXEC 0777
#define TRUE 1
#define FALSE 0
struct {
char control,opcode;
int bval,sn;
} binbuf, *binptr;
struct csect {
int dotsave, *tbuf,*rbuf,offset,tseek,rseek;
} csect[2];
struct {
char sname[8];
int sflag,svalue;
} *symtp , *symtab;
outf 0;
fin 0;
dot 0;
dotsect 0;
main (argc,argv)
int argc;
char *argv[];
{
char *ofile;
int nsymbol,header[8],i,symbytes;
int rword,word,x;
/* Interpret arguements ... must be
* arg1 pathname of symbol table file.
* arg2 pathname of intermediate binary file.
* arg3 (optional) pathname of output file.
*/
if (argc<3){
printf ("Input ??: symtab binary\n");
exit(1);
}
if ((fin=open(argv[1],0))<0){
printf ("Can't open %s\n",argv[1]);
exit(1);
}
symtab=sbrk(4*SYMSIZE);
if (read(fin,symtab,4*SYMSIZE)<4*SYMSIZE){
bst:
printf ("Bad Symbol table %s\n",argv[1]);
exit(1);
}
symbytes=(symtab[0].svalue-4)*SYMSIZE;
if (symbytes > 0)
{sbrk(symbytes);
if (read(fin,&symtab[4].sname[0],symbytes)<symbytes) goto bst;
}
close (fin); /* Later make this unlink*/
nsymbol=symtab[0].svalue;
/* Symbol table complete - Construct header for a.out file
*/
header[0]=0407;
header[1]=symtab[1].svalue; /* Size of .text*/
header[2]=symtab[2].svalue; /* Size of .data */
header[3]=symtab[3].svalue; /* Size of .bss */
header[4]=symtab->svalue*SYMSIZE; /* Size of symbol table */
header[5]=header[6]=header[7]=0;
/* Initialize the control section tables
*/
csect[0].tseek=16;
csect[0].rseek=header[1]+header[2]+16;
csect[0].tbuf=sbrk(BUFSIZE);
csect[0].rbuf=sbrk(BUFSIZE);
csect[0].dotsave=0;
csect[0].offset=0;
csect[1].tseek=header[1]+16;
csect[1].rseek=2*header[1]+header[2]+16;
csect[1].tbuf=sbrk(BUFSIZE);
csect[1].rbuf=sbrk(BUFSIZE);
/* ------When data starts on a segment boundary this will be valid-------
csect[1].dotsave=(header[1]+8191)&0160000;
----------------------------------------------------------------- */
csect[1].dotsave=header[1];
csect[1].offset=0;
symtab[0].svalue=0;
symtab[1].svalue=0;
symtab[2].svalue = header[1];
symtab[3].svalue = header[1] + header[2];
for (i = 4; i < nsymbol; i++)
if (x = symtab[i].sflag & 7)
symtab[i].svalue =+ symtab[x - 1].svalue;
if ((fin=open(argv[2],0))<0){
printf ("Can't open object file %s\n",argv[2]);
exit(1);
}
ofile="a.out";
if(argc>=4)ofile=argv[3];
if ((outf=creat(ofile,CBITS))<0){
printf("Can't create %s\n",ofile);
exit(1);
}
/* Initialization complete - begin loading
*/
x= TRUE;
while (read(fin,binptr,BINSIZE)>0){
rword=0;
word=binptr->bval;
if((i=symtab[binptr->sn].sflag&7)!=0){
rword= (i-1)<<1;
word=+ symtab[binptr->sn].svalue;
}
else if ((symtab[binptr->sn].sflag&EXTERN)!=0){
rword=(binptr->sn<<4)|010;
x= FALSE;
}
switch(binptr->control&3){
case ABSLOAD:
if ((binptr->control&4)!=0){
word=- (dot+2);
rword=| 1;
}
putword(word,rword);
break;
case BRANCH:
word=(binptr->opcode<<8)+ (((word-dot-2)>>1) & 0377);
putword(word,0); break;
case JUMP:
if ((i=binptr->opcode^1)!=0){
putword ((i<<8)+2,0);
}
putword(0167,0);
putword(word-dot-2,rword|1);
break;
case LOADELC:
csect[dotsect].dotsave=dot;
dotsect=(rword>>1)-1;
dot=csect[dotsect].dotsave;
while (dot<word){
putword(0,0);
}
break;
default:
printf("Invalid binary %o %o %o %o\n",binptr->control,
binptr->opcode,binptr->bval,binptr->sn);
exit(1);
}
}
if (csect[0].offset!=0)output(0);
if(csect[1].offset!=0)output(1);
seek(outf,2*(header[1]+header[2])+16,0);
write(outf,symtab,nsymbol*SYMSIZE);
seek(outf,0,0);
write (outf,header,16);
close(outf);
if (x== TRUE) chmod(ofile,EXEC);
close(fin);
exit(0);
}
putword (data,reloc)
int data,reloc;
{
int j;
j=csect[dotsect].offset;
csect[dotsect].tbuf[j]=data;
csect[dotsect].rbuf[j]=reloc;
if(++csect[dotsect].offset>=BUFEND)output(dotsect);
dot=+2;
}
output (section)
int section;
{
seek(outf,csect[section].tseek,0);
write(outf,csect[section].tbuf,2*csect[section].offset);
seek(outf,csect[section].rseek,0);
write(outf,csect[section].rbuf,2*csect[section].offset);
csect[section].tseek=+ 2*csect[section].offset;
csect[section].rseek=+ 2*csect[section].offset;
csect[section].offset=0;
}