SysIII/usr/src/cmd/sysfix.c

Compare this file to the similar file:
Show the results in this format:

/*
 * fix system image for I/D space
 *  Move data down to 0; move text to 4K.
 *  Also put the data at the start of the
 *  file and the text after it.
 */

#include <stdio.h>
FILE *tbuf;
FILE *rbuf;
FILE *obuf;
long	txtsiz;
long	datsiz;
unsigned bsssiz;
unsigned symsiz;

char	utsname[9];
unsigned utsseek 0;
int	symbuf[6];
int	txtrel	8192;
int	datrel;
FILE *symfd;
char	symname[9];

main(argc, argv)
char **argv;
{
	register word, rel;
	register unsigned s;

	if (argc<3) {
		fprintf(stderr,"Usage: sysfix a.out unix [utsname]\n");
		exit(1);
	}
	if (argc==4)
		strncpy(utsname, argv[3], 8);
	if ((tbuf = fopen(argv[1], "r"))==NULL) {
		fprintf(stderr,"Cannot open input %s\n",argv[1]);
		exit(1);
	}
	rbuf = fopen(argv[1], "r");
	symfd = fopen(argv[1], "r");
	if ((obuf = fopen(argv[2], "w"))==NULL) {
		fprintf(stderr,"Cannot create output %s\n",argv[2]);
		exit(1);
	}
	if (getw(tbuf) != 0407) {
		fprintf(stderr,"Bad input format\n");
		exit(1);
	}
	txtsiz = (unsigned)getw(tbuf);
	datsiz = (unsigned)getw(tbuf);
	bsssiz = getw(tbuf);
	symsiz = getw(tbuf);
	getw(tbuf);
	getw(tbuf);
	if (getw(tbuf) != 0) {
		fprintf(stderr,"No relocation bits\n");
		exit(1);
	}
	if ((datsiz+bsssiz) > 6*8192L) {
		fprintf(stderr,"combined data and bss size too big\n");
		exit(1);
	}
	if (txtsiz > 7*8192L) {
		fprintf(stderr,"text size too big\n");
		exit(1);
	}
	if ((txtsiz+datsiz+symsiz) > 7*8192L-1500) {
		fprintf(stderr,"Warning: ");
		fprintf(stderr,"combined program size too big for boot loader\n");
	}
	putw(0407, obuf);
	putw((short)txtsiz, obuf);
	putw((short)datsiz, obuf);
	putw(bsssiz, obuf);
	putw(symsiz, obuf);
	putw(0, obuf);
	putw(0, obuf);
	putw(1, obuf);
	datrel = -txtsiz;
/*
 *  Copy out data first
 */
	fseek(tbuf, 020+txtsiz, 0);
	fseek(rbuf, 020+txtsiz+txtsiz+datsiz, 0);
	s = datsiz >> 1;
	while (s--) {
		word = getw(tbuf);
		rel = getw(rbuf);
		if (rel&01)
			word -= datrel;
		word += getrel(rel);
		putw(word, obuf);
	}
/*
 * Now to the text.
 */
	fseek(rbuf, 020+txtsiz+datsiz, 0);
	fseek(tbuf, (long) 020, 0);
	s = txtsiz>>1;
	while(s--) {
		rel = getw(rbuf);
		word = getw(tbuf);
		if (rel&01)
			word -= txtrel;
		word += getrel(rel);
		putw(word, obuf);
	}
/*
 * The symbol table.
 */
	fseek(tbuf, 020+txtsiz+txtsiz+datsiz+datsiz, 0);
	s = symsiz;
	while (s) {
		fread(symbuf, 12, 1, tbuf);
		switch(symbuf[4]&07) {
			case 2:
				symbuf[5] += txtrel;
				break;
			case 3:
			case 4:
				symbuf[5] += datrel;
		}
		fwrite(symbuf, 12, 1, obuf);
		if (strncmp(symbuf, "_utsname", 8)==0 && symbuf[4]==043)
			utsseek = symbuf[5];
		s -= 12;
	}
	if (utsseek && utsname[0]) {
		fseek(obuf, (long)020+utsseek, 0);
		fwrite(utsname, 8, 1, obuf);
	}
	chmod(argv[2],0744);
}

getrel(r)
{
	int	off;
	switch (r&016) {

	case 02:	/* ref to text */
		return(txtrel);
	case 04:		/* ref to data */
	case 06:		/* ref to bss */
		return(datrel);
	case 0:
		return(0);
	case 010:
		off = ((r>>4) & 07777) * 12;
		fseek(symfd, 020+txtsiz+txtsiz+datsiz+datsiz+off,0);
		fread(symname, 8, 1, symfd);
		fprintf(stderr,"Undefined Symbol: %s\n",symname);
		return(0);
	default:
		fprintf(stderr,"Bad relocation %o\n", r);
		return(0);
	}
}