From 5140441585fa78d132eea5c21d5430f8c64a95a1 Mon Sep 17 00:00:00 2001 From: ceriel Date: Tue, 19 Apr 1988 09:27:51 +0000 Subject: [PATCH] Initial revision --- mach/minixST/.distr | 3 + mach/minixST/Action | 6 + mach/minixST/cv/.distr | 2 + mach/minixST/cv/Makefile | 25 +++ mach/minixST/cv/cv.c | 331 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 367 insertions(+) create mode 100644 mach/minixST/.distr create mode 100644 mach/minixST/Action create mode 100644 mach/minixST/cv/.distr create mode 100644 mach/minixST/cv/Makefile create mode 100644 mach/minixST/cv/cv.c diff --git a/mach/minixST/.distr b/mach/minixST/.distr new file mode 100644 index 000000000..f15502b4d --- /dev/null +++ b/mach/minixST/.distr @@ -0,0 +1,3 @@ +Action +cv +libsys diff --git a/mach/minixST/Action b/mach/minixST/Action new file mode 100644 index 000000000..9ac53acbf --- /dev/null +++ b/mach/minixST/Action @@ -0,0 +1,6 @@ +name "Atari ST Minix systemcall library" +dir libsys +end +name "Atari ST Minix conversion program from ack.out --> Minix ST a.out" +dir cv +end diff --git a/mach/minixST/cv/.distr b/mach/minixST/cv/.distr new file mode 100644 index 000000000..d7a861d66 --- /dev/null +++ b/mach/minixST/cv/.distr @@ -0,0 +1,2 @@ +Makefile +cv.c diff --git a/mach/minixST/cv/Makefile b/mach/minixST/cv/Makefile new file mode 100644 index 000000000..5cfa97a6a --- /dev/null +++ b/mach/minixST/cv/Makefile @@ -0,0 +1,25 @@ +EMHOME = ../../.. +LIBOBJ = $(EMHOME)/modules/lib/libobject.a +INCLUDE = $(EMHOME)/h +CFLAGS = -I. -I$(INCLUDE) -O +TARGETS = cv + +all: $(TARGETS) + +install: all + ../../install cv + +cmp: all + ../../compare cv + +cv: cv.o + $(CC) $(LDFLAGS) -o cv cv.o $(LIBOBJ) + +clean: + rm -f $(TARGETS) *.o nohup.out Out + +pr: + @pr Makefile cv.c + +opr: + make pr | opr diff --git a/mach/minixST/cv/cv.c b/mach/minixST/cv/cv.c new file mode 100644 index 000000000..709512c48 --- /dev/null +++ b/mach/minixST/cv/cv.c @@ -0,0 +1,331 @@ +/* $Header$ */ +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + * + */ + +/* + * Convert ACK a.out file to ST-Minix object format. + */ + +#include +#include +#include + +struct outhead outhead; +struct outsect outsect[S_MAX]; + +#define TEXTSG 0 +#define ROMSG 1 +#define DATASG 2 +#define BSSSG 3 +#define LSECT BSSSG+1 +#define NSECT LSECT+1 + +char *output_file; +int outputfile_created; + +char *program ; + +/* Output file definitions and such */ + +int output; + +int unresolved; +long textsize ; +long datasize ; +long bsssize; + +char *chmemstr; + +minixhead() +{ + long mh[8]; + long stack; + long chmem(); + int i; + + mh[0] = 0x04100301L; + mh[1] = 0x00000020L; + mh[2] = textsize; + mh[3] = datasize; + mh[4] = bsssize; + mh[5] = 0; + stack = 0x00010000L - (mh[3] + mh[4]); + if ((mh[0] & 0x00200000L) == 0) /* not SEPARATE */ + stack -= mh[2]; + while (stack < 0) + stack += 0x00010000L; + if (chmemstr) + stack = chmem(chmemstr, stack); + printf("%D bytes assigned to stack+malloc area\n", stack); + mh[6] = stack + (mh[3] + mh[4]); + if ((mh[0] & 0x00200000L) == 0) /* not SEPARATE */ + mh[6] += mh[2]; + mh[7] = 0; + for (i = 0; i < 8; i++) { + cvlong(&mh[i]); + } + + if (write(output, (char *) mh, sizeof(mh)) != sizeof(mh)) + fatal("write error\n"); +} + +long align(a,b) + long a,b; +{ + if (b == 0) return a; + a += b - 1; + return a - a % b; +} + +int +follows(pa, pb) + register struct outsect *pa, *pb; +{ + /* return 1 if pa follows pb */ + + return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign); +} + +main(argc, argv) + int argc; + char *argv[]; +{ + + program= argv[0] ; + if (argc > 1) { + switch (argv[1][0]) { + case '-': + case '+': + case '=': + chmemstr = argv[1]; + argc--; + argv++; + } + } + switch (argc) { + case 3: if ((output = creat(argv[2], 0644)) < 0) + fatal("Can't write %s.\n", argv[2]); + output_file = argv[2]; + outputfile_created = 1; + if (! rd_open(argv[1])) + fatal("Can't read %s.\n", argv[1]); + break; + default:fatal("Usage: %s [+-= amount] .\n", argv[0]); + } + rd_ohead(&outhead); + if (BADMAGIC(outhead)) + fatal("Not an ack object file.\n"); + if (outhead.oh_flags & HF_LINK) { + unresolved++; + fatal("Contains unresolved references.\n"); + } + if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT ) + fatal("Input file must have %d sections, not %ld\n", + NSECT,outhead.oh_nsect) ; + rd_sect(outsect, outhead.oh_nsect); + /* A few checks */ + if ( outsect[BSSSG].os_flen != 0 ) + fatal("bss space contains initialized data\n") ; + if (! follows(&outsect[BSSSG], &outsect[DATASG])) + fatal("bss segment must follow data segment\n") ; + textsize= (outsect[DATASG].os_base - outsect[TEXTSG].os_base); + if (! follows(&outsect[ROMSG],&outsect[TEXTSG])) + fatal("rom segment must follow text\n") ; + if (! follows(&outsect[DATASG],&outsect[ROMSG])) + fatal("data segment must follow rom\n") ; + outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base; + outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base; + outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base; + datasize= outsect[DATASG].os_size ; + bsssize = outsect[BSSSG].os_size; + if ( outhead.oh_nsect==NSECT ) { + if (! follows(&outsect[LSECT],&outsect[BSSSG])) + fatal("end segment must follow bss\n") ; + if ( outsect[LSECT].os_size != 0 ) + fatal("end segment must be empty\n") ; + } + + minixhead(); + emits(&outsect[TEXTSG]) ; + emits(&outsect[ROMSG]) ; + emits(&outsect[DATASG]) ; + emit_relo(); + if ( outputfile_created) chmod(argv[2],0755); + return 0; +} + +/* + * Transfer the emitted byted from one file to another. + */ +emits(section) struct outsect *section ; { + char *p; + char *calloc(), *malloc(); + long sz = section->os_flen; + + rd_outsect(section - outsect); + while (sz) { + unsigned int i = (sz >= 0x4000 ? 0x4000 : sz); + if (!(p = malloc(0x4000))) { + fatal("No memory.\n"); + } + rd_emit(p, (long) i); + if (write(output, p, (int)i) < i) { + fatal("write error.\n"); + } + free(p); + sz -= i; + } + + sz = section->os_size - section->os_flen; + if (sz) { + if (!(p = calloc(0x4000, 1))) { + fatal("No memory.\n"); + } + while (sz) { + unsigned int i = (sz >= 0x4000 ? 0x4000 : sz); + if (write(output, p, (int)i) < i) { + fatal("write error.\n"); + } + sz -= i; + } + free(p); + } +} + +int +compare(a,b) + register struct outrelo *a, *b; +{ + if (a->or_sect < b->or_sect) return -1; + if (a->or_sect > b->or_sect) return 1; + if (a->or_addr < b->or_addr) return -1; + if (a->or_addr > b->or_addr) return 1; + return 0; +} + +emit_relo() +{ + struct outrelo *ACKrelo; + register struct outrelo *ap; + unsigned int cnt = outhead.oh_nrelo; + long last, curr, base; + int sect; + char *bp; + register char *b; + + ACKrelo = ap = (struct outrelo *) calloc(cnt, sizeof(struct outrelo)); + bp = b = malloc(4 + cnt); + if (!ap || !bp) { + fatal("No memory.\n"); + } + rd_relo(ap, cnt); + qsort((char *) ap, (int) cnt, sizeof(struct outrelo), compare); + /* + * read relocation, modify to GEMDOS format, and write. + * Only longs can be relocated. + * + * The GEMDOS format starts with a long L: the offset to the + * beginning of text for the first long to be relocated. + * If L==0 then no relocations have to be made. + * + * The long is followed by zero or more bytes. Each byte B is + * processed separately, in one of the following ways: + * + * B==0: + * end of relocation + * B==1: + * no relocation, but add 254 to the current offset + * B==0bWWWWWWW0: + * B is added to the current offset and the long addressed + * is relocated. Note that 00000010 means 1 word distance. + * B==0bXXXXXXX1: + * illegal + */ + + last = 0; + curr = 0; + for (sect = S_MIN; sect <= S_MIN+2; sect++) { + base = outsect[sect-S_MIN].os_base; + for (;cnt > 0 && ap->or_sect == sect; ap++, cnt--) { + if (ap->or_type & RELPC || + ap->or_nami == outhead.oh_nname) { + continue; + } + assert(ap->or_type & RELO4); + curr = base + ap->or_addr; + if (last == 0) { + last = curr; + cvlong(&curr); + *((long *) b) = curr; + b += 4; + } + else { + while (curr - last > 255) { + *b++ = 1; + last += 254; + } + *b++ = curr - last; + last = curr; + } + } + assert(cnt == 0 || ap->or_sect > sect); + } + assert(cnt == 0); + if (cnt = (b - bp)) { + *b++ = '\0'; + write(output, bp, (int) cnt+1); + } + else write(output, "\0\0\0", 4); + free((char *) ACKrelo); + free(bp); +} + +long +chmem(str, old) +char *str; +long old; +{ + register long num, new; + long atol(); + + num = atol(str+1); + if (num == 0) + fatal("bad chmem amount %s\n", str+1); + switch (str[0]) { + case '-': + new = old - num; break; + case '+': + new = old + num; break; + case '=': + new = num; break; + } + return(new); +} + +cvlong(l) + long *l; +{ + long x = *l; + char *p = (char *) l; + + *p++ = x >> 24; + *p++ = x >> 16; + *p++ = x >> 8; + *p = x; +} + +/* VARARGS1 */ +fatal(s, a1, a2) + char *s; +{ + fprintf(stderr,"%s: ",program) ; + fprintf(stderr, s, a1, a2); + if (outputfile_created) + unlink(output_file); + exit(-1); +} + +rd_fatal() { fatal("read error.\n"); }