[comp.os.minix] MINIX-ST 1.1 patch #12: source fixes for /usr/lib/cv

hcj@lzaz.ATT.COM (HC Johnson) (06/19/89)

In article <259@nlgvax.UUCP>, johan@nlgvax.UUCP (Johan Stevenson) writes:
> 
> Because of still more problems with the loadfile conversion program
> I decided to post the sources. This part of the compiler kit is fully
> designed for MINIX ST, so has no direct relation to the full
> Amsterdam Compiler Kit, copyrighted by the Vrije Universiteit.
> Hopefully posting helps to get the last bugs out. Please let me know
> of any, so I can correct the master copy accordingly.

I've build this version and it works on kernel pieces that failed on the
previous version.

Some casual observations on the program.
1. it does not use fread, and should survive 'large programs'
2. it uses calloc, which while it claims to accept an unsigned int, DOES NOT.
	This limits cv to handling a program of total size =
	32K X 8 == 256K (this is the space occupied by relocatables).

Thank you Johan for both repairing and posting this program.

Howard C. Johnson
ATT Bell Labs
att!lzaz!hcj
hcj@lzaz.att.com

johan@nlgvax.UUCP (Johan Stevenson) (07/23/89)

Because of still more problems with the loadfile conversion program
I decided to post the sources. This part of the compiler kit is fully
designed for MINIX ST, so has no direct relation to the full
Amsterdam Compiler Kit, copyrighted by the Vrije Universiteit.
Hopefully posting helps to get the last bugs out. Please let me know
of any, so I can correct the master copy accordingly.
You will note the slightly different Makefile conventions. Type
	make minix
to get the program compiled on the ST under MINIX.

This message contains a shar wrapping of the following files:
	$ crc *
	07993    698 Makefile
	27804   8353 cv.c
	23828   3238 out.h
Go to an empty directory, feed the lines following the cut mark
to the shell, check the table above with the output of /usr/bin/crc
and install as follows:
	$ cp * /usr/src/ack/cv
	$ cd /usr/src/ack/cv
	$ make cv
	$ cp cv /usr/lib/cv
Good luck.
--
Johan W. Stevenson	johan@pcg.philips.nl		Philips Research
------------------------------------------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Makefile cv.c out.h
# Wrapped by johan@echo on Sat Jun 17 21:16:31 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(698 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# make minix: make a binary on Minix for Minix
X# make unix:  make a binary on Unix for Unix
X# make cross: make a binary on Unix for Minix
X#
X
XXCCDIR	= ../bin
XINCDIR	= ../../include
XCFLAGS	= -O -I.
X
XBINm	= cv
XBINu	= ../bin/cv
XBINc	= ../binst/cv
X
XSRC	= cv.c
XOBJ	= cv.o
X
Xall:
X	@echo "Please type 'make minix' or 'make unix' or 'make cross'"
X
Xminix:	$(BINm)
Xunix:	$(BINu)
Xcross:	$(BINc)
X
X$(BINm):$(OBJ)
X	cc -o $@ $(OBJ)
X	chmem =50000 $@
X
X$(BINu):$(SRC) 
X	cc $(CFLAGS) -DUNIX -o $@ $(SRC)
X
X$(BINc):$(SRC)
X	$(XCCDIR)/cc -I$(INCDIR) $(CFLAGS) -o $@ $(SRC)
X	$(XCCDIR)/chmem =50000 $@
X
Xkit:
X	rm -rf SRC SRCZ.a; mkdir SRC
X	cp *.h *.c SRC
X	cd SRC; compress -f -b13 *
X	../bin/ar r SRCZ.a SRC/?*.Z
X	rm -rf SRC
END_OF_FILE
if test 698 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'cv.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'cv.c'\"
else
echo shar: Extracting \"'cv.c'\" \(8353 characters\)
sed "s/^X//" >'cv.c' <<'END_OF_FILE'
X/*
X * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
X * See the copyright notice in the file "../Copyright".
X */
X/*
X * Convert ACK a.out file to ST-Minix object format.
X */
X
X#include <stdio.h>
X#include <out.h>
X
X#define TXTSEG	0
X#define ROMSEG	1
X#define DATSEG	2
X#define BSSSEG	3
X#define ENDSEG	4
X
Xstruct outhead	outhead;
Xstruct outsect	outsect[ENDSEG+1];
X
Xint	Rflag;
X
Xchar	*output_file;
Xchar	*program;
Xchar	*chmemstr;
X
Xmain(argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	register int	i;
X
X	program = argv[0];
X	while (argc > 1) {
X		switch (argv[1][0]) { 
X		case '-':
X			if (strcmp(argv[1], "-R") == 0) {
X				Rflag++;
X				argc--;
X				argv++;
X				continue;
X			}
X			/* fall through */
X		case '+':
X		case '=':
X			chmemstr = argv[1];
X			argc--;
X			argv++;
X			continue;
X		}
X		break;
X	}
X	if (argc != 3)
X		fatal("Usage: %s [-R] [+-= amount] <ACK object> <MINIX-ST object>", argv[0]);
X
X	if ((freopen(argv[1], "r", stdin)) == NULL)
X		fatal("Can't read %s", argv[1]);
X	if ((freopen(argv[2], "w", stdout)) == NULL)
X		fatal("Can't write %s", argv[2]);
X	output_file = argv[2];
X
X	getofmt((char *)&outhead, SF_HEAD, stdin);
X	if (BADMAGIC(outhead))
X		fatal("Not an ack object file");
X	if (outhead.oh_flags & HF_LINK)
X		fatal("Contains unresolved references");
X	if (outhead.oh_nsect < BSSSEG+1)
X		fatal("Input must have at least %d sections, not %ld",
X			BSSSEG+1, outhead.oh_nsect);
X	if (outhead.oh_nsect > ENDSEG+1)
X		fatal("Input must have at most %d sections, not %ld",
X			ENDSEG+1, outhead.oh_nsect);
X	for (i = 0; i < outhead.oh_nsect; i++)
X		getofmt((char *)&outsect[i], SF_SECT, stdin);
X
X	/* A few checks */
X	if (outsect[BSSSEG].os_flen != 0)
X		fatal("bss contains initialized data");
X	if (! follows(ROMSEG, TXTSEG))
X		fatal("rom must follow text");
X	if (! follows(DATSEG, ROMSEG))
X		fatal("data must follow rom");
X	if (! follows(BSSSEG, DATSEG))
X		fatal("bss must follow data");
X	outsect[TXTSEG].os_size = outsect[ROMSEG].os_base - outsect[TXTSEG].os_base;
X	outsect[ROMSEG].os_size = outsect[DATSEG].os_base - outsect[ROMSEG].os_base;
X	outsect[DATSEG].os_size = outsect[BSSSEG].os_base - outsect[DATSEG].os_base;
X	if (outhead.oh_nsect == ENDSEG+1) {
X		if (! follows(ENDSEG, BSSSEG))
X			fatal("end segment must follow bss");
X		if (outsect[ENDSEG].os_size != 0)
X			fatal("end segment must be empty");
X	}
X	emit_head();
X	emit_sect(TXTSEG);
X	emit_sect(ROMSEG);
X	emit_sect(DATSEG);
X	emit_relo();
X#ifndef UNIX
X	if (output_file) chmod(output_file, 0777 & ~umask(0));
X#endif
X	exit(0);
X}
X
Xemit_head()
X{
X	register	i;
X	long		mh[8];
X	long		stack;
X	long		chmem();
X
X	mh[0] = 0x04100301L;
X	mh[1] = 0x00000020L;
X	mh[2] = outsect[TXTSEG].os_size + outsect[ROMSEG].os_size;
X	mh[3] = outsect[DATSEG].os_size;
X	mh[4] = outsect[BSSSEG].os_size;
X	mh[5] = 0;
X	stack = 0x00010000L - (mh[3] + mh[4]);
X	if ((mh[0] & 0x00200000L) == 0)		/* not SEPARATE */
X		stack -= mh[2];
X	while (stack < 0)
X		stack += 0x00010000L;
X	if (chmemstr)
X		stack = chmem(chmemstr, stack);
X	fprintf(stderr, "%D bytes assigned to stack+malloc area\n", stack);
X	mh[6] = stack + (mh[3] + mh[4]);
X	if ((mh[0] & 0x00200000L) == 0)		/* not SEPARATE */
X		mh[6] += mh[2];
X	mh[7] = 0;
X	for (i = 0; i < 8; i++)
X		putlong(mh[i], stdout);
X}
X
Xfollows(segb, sega)
X{
X	register struct outsect *pb = &outsect[segb];
X	register struct outsect *pa = &outsect[sega];
X	register long		b;
X
X	/* return 1 if segb follows sega */
X
X	b = pa->os_base + pa->os_size;
X	if (pb->os_lign) {
X		b += pb->os_lign - 1;
X		b -= b % pb->os_lign;
X	}
X	return(pb->os_base == b);
X}
X
X/*
X * Transfer the emitted byted from one file to another.
X */
Xemit_sect(seg)
X{
X	register struct outsect *sp = &outsect[seg];
X	register long		sz = sp->os_flen;
X	register int		c;
X
X	fseek(stdin, sp->os_foff, 0);
X	for (sz = sp->os_flen; sz > 0; sz--) {
X		c = getc(stdin);
X		if (c == EOF)
X			rderr();
X		c = putc(c, stdout);
X		if (c == EOF)
X			wrerr();
X	}
X	for (sz = sp->os_size - sp->os_flen; sz > 0; sz--) {
X		c = putc(0, stdout);
X		if (c == EOF)
X			wrerr();
X	}
X}
X
Xemit_relo()
X{
X	register char	*ptr;
X	register int	len;
X	register int	bit;
X	register int	byt;
X	register long	last;
X	register long	curr;
X	register long	base;
X	register long	stop;
X	register long	i;
X	struct outrelo	outrelo;
X	extern char	*calloc();
X
X	if (Rflag) {
X		putlong(0L, stdout);
X		return;
X	}
X	fseek(stdin, OFF_RELO(outhead), 0);
X	base = outsect[TXTSEG].os_base;
X	stop = outsect[BSSSEG].os_base;
X	len = (int)(((stop - base) + 15) / 16);
X	if (len != (((stop - base) + 15) / 16))
X		fatal("relo: span too big");
X	ptr = calloc(len, 1);
X	if (ptr == NULL)
X		fatal("out of memory");
X	for (i = outhead.oh_nrelo; i > 0; i--) {
X		getofmt((char *)&outrelo, SF_RELO, stdin);
X		if (outrelo.or_type & RELPC)
X			continue;
X		if (outrelo.or_nami == outhead.oh_nname)
X			continue;
X		if ((outrelo.or_type & (RELBR|RELWR)) != (RELBR|RELWR))
X			fatal("relo: not for 680X0");
X		if ((outrelo.or_type & RELSZ) != RELO4) {
X			static int warned;
X			if (!warned) {
X				fprintf(stderr, "only longs can be relocated\n");
X				warned++;
X			}
X		}
X		outrelo.or_sect -= S_MIN;
X		if (outrelo.or_sect < TXTSEG || outrelo.or_sect > DATSEG)
X			fatal("relo: bad section");
X		curr = outrelo.or_addr;
X		curr += outsect[outrelo.or_sect].os_base;
X		if (curr < base || curr >= stop)
X			fatal("relo: bad address");
X		curr -= base;
X		if (curr & 1)
X			fatal("relo: odd address");
X		curr >>= 1;
X		byt = (int)(curr >> 3);
X		bit = 1 << ((int)curr & 7);
X		if (ptr[byt] & bit)
X			fatal("relo: twice on same address");
X		ptr[byt] |= bit;
X	}
X	/*
X         * read relocation, modify to GEMDOS format, and write.
X         * Only longs can be relocated.
X         *
X         * The GEMDOS format starts with a long L: the offset to the
X         * beginning of text for the first long to be relocated.
X         * If L==0 then no relocations have to be made.
X         *
X         * The long is followed by zero or more bytes. Each byte B is
X         * processed separately, in one of the following ways:
X         *
X         * B==0:
X         *      end of relocation
X         * B==1:
X         *      no relocation, but add 254 to the current offset
X         * B==0bWWWWWWW0:
X         *      B is added to the current offset and the long addressed
X         *      is relocated. Note that 00000010 means 1 word distance.
X         * B==0bXXXXXXX1:
X         *      illegal
X         */
X	last = 0;
X	for (byt = 0; byt < len; byt++) {
X		if (ptr[byt] == 0)
X			continue;
X		for (bit = 0; bit < 8; bit++) {
X			if ((ptr[byt] & (1<<bit)) == 0)
X				continue;
X			curr = ((long)byt << 3) + bit;
X			curr <<= 1;
X			curr += base;
X			if (last == 0)
X				putlong(curr, stdout);
X			else {
X				while (curr - last > 255) {
X					if (putc(1, stdout) == EOF)
X						wrerr();
X					last += 254;
X				}
X				if (putc((int)(curr - last), stdout) == EOF)
X					wrerr();
X			}
X			last = curr;
X		}
X	}
X	if (last == 0)
X		putlong(last, stdout);
X	else {
X		if (putc(0, stdout) == EOF)
X			wrerr();
X	}
X	free(ptr);
X}
X
Xlong
Xchmem(str, old)
Xchar *str;
Xlong old;
X{
X        register long num, new;
X        long atol();
X
X        num = atol(str+1);
X        if (num == 0)
X                fatal("bad chmem amount %s", str+1);
X        switch (str[0]) {
X        case '-':
X                new = old - num; break;
X        case '+':
X                new = old + num; break;
X        case '=':
X                new = num; break;
X        }
X        return(new);
X}
X
X/* VARARGS1 */
Xfatal(s, a1, a2, a3, a4, a5)
X	char	*s;
X{
X	fprintf(stderr, "%s: ", program);
X	fprintf(stderr, s, a1, a2, a3, a4, a5);
X	fprintf(stderr, "\n");
X	if (output_file)
X		unlink(output_file);
X	exit(-1);
X}
X
Xrderr()
X{
X	fatal("read error");
X}
X
Xwrerr()
X{
X	fatal("write error");
X}
X
Xgetofmt(p, s, f)
Xregister char	*p;
Xregister char	*s;
Xregister FILE	*f;
X{
X	register i;
X	register long l;
X
X	for (;;) {
X		switch (*s++) {
X/*		case '0': p++; continue; */
X		case '1':
X			*p++ = getc(f);
X			continue;
X		case '2':
X			i = getc(f);
X			i |= (getc(f) << 8);
X			*((short *)p) = i; p += sizeof(short);
X			continue;
X		case '4':
X			l = (long)getc(f);
X			l |= ((long)getc(f) << 8);
X			l |= ((long)getc(f) << 16);
X			l |= ((long)getc(f) << 24);
X			*((long *)p) = l; p += sizeof(long);
X			continue;
X		default:
X			fatal("bad getofmt");
X		case '\0':
X			break;
X		}
X		break;
X	}
X	if (feof(f) || ferror(f))
X		rderr();
X}
X
Xputlong(l, f)
Xlong		l;
Xregister FILE	*f;
X{
X	putc((int)(l>>24), f);
X	putc((int)(l>>16), f);
X	putc((int)(l>>8 ), f);
X	putc((int)(l    ), f);
X	if (ferror(f))
X		wrerr();
X}
END_OF_FILE
if test 8353 -ne `wc -c <'cv.c'`; then
    echo shar: \"'cv.c'\" unpacked with wrong size!
fi
# end of 'cv.c'
fi
if test -f 'out.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'out.h'\"
else
echo shar: Extracting \"'out.h'\" \(3238 characters\)
sed "s/^X//" >'out.h' <<'END_OF_FILE'
X/*
X * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
X * See the copyright notice in the file "../Copyright".
X */
X/*
X * output format for ACK assemblers
X */
X#ifndef ushort
X#define ushort	unsigned short
X#endif ushort
X
Xstruct outhead {
X	ushort 	oh_magic;	/* magic number */
X	ushort 	oh_stamp;	/* version stamp */
X	ushort	oh_flags;	/* several format flags */
X	ushort	oh_nsect;	/* number of outsect structures */
X	ushort	oh_nrelo;	/* number of outrelo structures */
X	ushort	oh_nname;	/* number of outname structures */
X	long	oh_nemit;	/* sum of all os_flen */
X	long	oh_nchar;	/* size of string area */
X};
X
X#define O_MAGIC	0x0201		/* magic number of output file */
X#define	O_STAMP	0		/* version stamp */
X#define MAXSECT	64		/* Maximum number of sections */
X
X#define	HF_LINK	0x0004		/* unresolved references left */
X#define	HF_8086	0x0008		/* os_base specially encoded */
X
Xstruct outsect {
X	long 	os_base;	/* startaddress in machine */
X	long	os_size;	/* section size in machine */
X	long	os_foff;	/* startaddress in file */
X	long	os_flen;	/* section size in file */
X	long	os_lign;	/* section alignment */
X};
X
Xstruct outrelo {
X	char	or_type;	/* type of reference */
X	char	or_sect;	/* referencing section */
X	ushort	or_nami;	/* referenced symbol index */
X	long	or_addr;	/* referencing address */
X};
X
Xstruct outname {
X	union {
X	  char	*on_ptr;	/* symbol name (in core) */
X	  long	on_off;		/* symbol name (in file) */
X	}	on_u;
X#define on_mptr	on_u.on_ptr
X#define on_foff	on_u.on_off
X	ushort	on_type;	/* symbol type */
X	ushort	on_desc;	/* debug info */
X	long	on_valu;	/* symbol value */
X};
X
X/*
X * relocation type bits
X */
X#define RELSZ	0x07		/* relocation length */
X#define RELO1	   1		/* 1 byte */
X#define RELO2	   2		/* 2 bytes */
X#define RELO4	   4		/* 4 bytes */
X#define RELPC	0x08		/* pc relative */
X#define RELBR	0x10		/* High order byte lowest address. */
X#define RELWR	0x20		/* High order word lowest address. */
X
X/*
X * section type bits and fields
X */
X#define S_TYP	0x007F		/* undefined, absolute or relative */
X#define S_EXT	0x0080		/* external flag */
X#define S_ETC	0x7F00		/* for symbolic debug, bypassing 'as' */
X
X/*
X * S_TYP field values
X */
X#define S_UND	0x0000		/* undefined item */
X#define S_ABS	0x0001		/* absolute item */
X#define S_MIN	0x0002		/* first user section */
X#define S_MAX	S_TYP		/* last user section */
X
X/*
X * S_ETC field values
X */
X#define S_SCT	0x0100		/* section names */
X#define S_LIN	0x0200		/* hll source line item */
X#define S_FIL	0x0300		/* hll source file item */
X#define S_MOD	0x0400		/* ass source file item */
X#define S_COM	0x1000		/* Common name. */
X
X/*
X * structure format strings
X */
X#define SF_HEAD		"22222244"
X#define SF_SECT		"44444"
X#define SF_RELO		"1124"
X#define SF_NAME		"4224"
X
X/*
X * structure sizes (bytes in file; add digits in SF_*)
X */
X#define SZ_HEAD		20
X#define SZ_SECT		20
X#define SZ_RELO		8
X#define SZ_NAME		12
X
X/*
X * file access macros
X */
X#define BADMAGIC(x)	((x).oh_magic!=O_MAGIC)
X#define OFF_SECT(x)	SZ_HEAD
X#define OFF_EMIT(x)	(OFF_SECT(x) + ((long)(x).oh_nsect * SZ_SECT))
X#define OFF_RELO(x)	(OFF_EMIT(x) + (x).oh_nemit)
X#define OFF_NAME(x)	(OFF_RELO(x) + ((long)(x).oh_nrelo * SZ_RELO))
X#define OFF_CHAR(x)	(OFF_NAME(x) + ((long)(x).oh_nname * SZ_NAME))
END_OF_FILE
if test 3238 -ne `wc -c <'out.h'`; then
    echo shar: \"'out.h'\" unpacked with wrong size!
fi
# end of 'out.h'
fi
echo shar: End of shell archive.
exit 0