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