From 027b33d313113ff1b6c442365bc24fd7d0e89459 Mon Sep 17 00:00:00 2001 From: ceriel Date: Fri, 12 Jan 1990 16:58:02 +0000 Subject: [PATCH] VAX a.out to ACK a.out conversion program, first version --- mach/vax4/cv/Makefile | 25 ++ mach/vax4/cv/cv.c | 588 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 613 insertions(+) create mode 100644 mach/vax4/cv/Makefile create mode 100644 mach/vax4/cv/cv.c diff --git a/mach/vax4/cv/Makefile b/mach/vax4/cv/Makefile new file mode 100644 index 000000000..5cfa97a6a --- /dev/null +++ b/mach/vax4/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/vax4/cv/cv.c b/mach/vax4/cv/cv.c new file mode 100644 index 000000000..b2fde4d77 --- /dev/null +++ b/mach/vax4/cv/cv.c @@ -0,0 +1,588 @@ +/* $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 VAX Berkeley Unix object format. + */ + +#include +#include +#include + +long lseek(); + +#define OMAGIC 0407 /* old-fashioned */ +#define NMAGIC 0410 /* text write protexted */ +#define ZMAGIC 0413 /* demand paging */ + +struct bhdr { + long magic; + long tsize; + long dsize; + long bsize; + long ssize; + long entry; + long rtsize; + long rdsize; +}; + +struct machrelo { + long address; + long relodata; +}; +#define setpcrel(X,f) (X |= (f<<7)) +#define setsymbolnum(X,n) (X = (X & 0377) | ((long)n << 8)) +#define setextern(X,f) (X |= (f << 4)) +#define setlength(X,l) (X = (X & ~0x60)|((long) l << 5)) + +struct sym { + long name; + char type; + char other; + short desc; + long value; +}; + +#define N_UNDF 0 +#define N_ABS 02 +#define N_TEXT 04 +#define N_DATA 06 +#define N_BSS 010 +#define N_EXT 01 +#define N_FN 0x1f + +/* + * Header and section table of new format object file. + */ +struct outhead outhead; +struct outsect outsect[S_MAX]; + +char *output_file; +int outputfile_created; +long magic; + +int rom_in_data; + +char *program ; + +char flag ; + +/* Output file definitions and such */ + +struct bhdr bh; + +#define ENTRY 0x0 +#define TOT_HDRSIZE (sizeof(struct bhdr)) + + + +#define TEXTSG 0 +#define ROMSG 1 +#define DATASG 2 +#define BSSSG 3 +#define LSECT BSSSG+1 +#define NSECT LSECT+1 + +int output; + +int unresolved; +int nflag; +long textsize ; +long datasize ; +long bsssize; + +long align(a,b) + long a,b; +{ + 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[]; +{ + register int nsect; + + program= argv[0] ; + while ( argc>1 && argv[1][0]=='-' ) { + flag=argv[1][1] ; + if (flag == 'u') unresolved++; + else if (flag == 'n') nflag = 1; + argc-- ; argv++ ; + } + switch (argc) { + case 3: if ((output = creat(argv[2], 0644)) < 0 || + (close(output), output = open(argv[2],2)) < 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 [-u] [-n] .\n", program); + } + rd_ohead(&outhead); + if (BADMAGIC(outhead)) + fatal("Not an ack object file.\n"); + if (outhead.oh_flags & HF_LINK) { + if (! unresolved) { + fprintf(stderr,"Warning: contains unresolved references.\n"); + } + unresolved++; + } + else if (outhead.oh_nrelo > 0 && !unresolved) + fprintf(stderr, "Warning: relocation information present.\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 ( !unresolved && ! follows(&outsect[BSSSG], &outsect[DATASG])) + fatal("bss segment must follow data segment\n") ; + 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; + if ( outsect[ROMSG].os_lign == 0x400 ) { + /* 410/413 file with ROMSG in data space */ + rom_in_data = 1; + magic= NMAGIC ; + textsize= outsect[TEXTSG].os_size; + datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ; + } else + if ( outsect[DATASG].os_lign == 0x400 ) { + /* 410/413 file with ROMSG in instruction space */ + rom_in_data = 0; + magic= NMAGIC ; + textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ; + datasize= outsect[DATASG].os_size ; + } else { + /* Plain 407 file */ + rom_in_data = 0; + magic= OMAGIC ; + textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ; + datasize = outsect[DATASG].os_size; + } + bsssize = outsect[BSSSG].os_size; + if (nflag && magic != NMAGIC) { + fatal("illegal alignments.\n"); + } + if (magic == NMAGIC && ! nflag) { + if (datasize & 0x3ff) { + int diff = 0x400 - (datasize & 0x3ff); + + if (bsssize >= diff) bsssize -= diff; + else bsssize = 0; + outsect[DATASG].os_size += diff; + datasize += diff; + } + magic = ZMAGIC; + } + 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") ; + } + + if (magic != OMAGIC && unresolved) { + fatal("unresolved references with wrong magic number\n"); + } + + if (outsect[TEXTSG].os_base != ENTRY) { + fatal("Illegal entry point.\n"); + } + + bh.magic = magic; + bh.tsize = textsize; + bh.bsize = bsssize; + bh.dsize = datasize; + bh.rtsize = 0; + bh.rdsize = 0; + bh.entry = ENTRY; + + /* Action at last */ + if (magic == ZMAGIC) { + lseek(output,(long) 0x400, 0); + } + else lseek(output,(long) TOT_HDRSIZE,0); + emits(&outsect[TEXTSG]) ; + emits(&outsect[ROMSG]) ; + emits(&outsect[DATASG]) ; + if (unresolved) emit_relo(); + emit_symtab(); + bh.ssize = outhead.oh_nname * sizeof(struct sym); + lseek(output,0L,0); + cvlong(&(bh.magic)); + cvlong(&(bh.tsize)); + cvlong(&(bh.dsize)); + cvlong(&(bh.bsize)); + cvlong(&(bh.ssize)); + cvlong(&(bh.entry)); + cvlong(&(bh.rtsize)); + cvlong(&(bh.rdsize)); + writef(&bh, 1, (long) TOT_HDRSIZE); + if ( outputfile_created && !unresolved ) chmod(argv[2],0755); + exit(0); +} + +writef(addr,sz,cnt) + char *addr; + long cnt; +{ + cnt *= sz; + + while (cnt) { + int i = cnt >= 0x4000 ? 0x4000 : cnt; + + cnt -= i; + if (write(output, addr, i) < i) { + fatal("write error\n"); + } + addr += i; + } +} + +/* + * 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(i))) { + fatal("No memory.\n"); + } + rd_emit(p, i); + if (write(output, p, 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, i) < i) { + fatal("write error.\n"); + } + sz -= i; + } + free(p); + } +} + +struct outname *ACKnames; + +emit_relo() +{ + struct outrelo *ACKrelo; + struct machrelo *MACHtrelo,*MACHdrelo; + register struct outrelo *ap; + register struct machrelo *mtp, *mdp; + unsigned int cnt = outhead.oh_nrelo; + + ACKrelo = (struct outrelo *) calloc(cnt, sizeof(struct outrelo)); + MACHtrelo = (struct machrelo *) calloc(cnt, sizeof(struct machrelo)); + MACHdrelo = (struct machrelo *) calloc(cnt, sizeof(struct machrelo)); + ACKnames = (struct outname *) calloc(outhead.oh_nname, sizeof(struct outname)); + if (!(ap = ACKrelo) || !(mtp = MACHtrelo) || !(mdp = MACHdrelo) || + !ACKnames) { + fatal("No memory.\n"); + } + rd_relo(ACKrelo, cnt); + rd_name(ACKnames, outhead.oh_nname); + while (cnt-- != 0) { + register struct machrelo *mp; + + if (ap->or_sect - S_MIN <= ROMSG) mp = mtp++; + else mp = mdp++; + setlength(mp->relodata,(ap->or_type&RELSZ) >> 1); + setpcrel(mp->relodata,(ap->or_type&RELPC != 0)); + mp->address = ap->or_addr; + if (ap->or_sect == ROMSG+S_MIN) { + mp->address += outsect[TEXTSG].os_size; + } + if (ap->or_nami < outhead.oh_nname) { + if (ACKnames[ap->or_nami].on_type & S_EXT) { + setsymbolnum(mp->relodata, ap->or_nami); + setextern(mp->relodata,1); + } + else { + patch(ap, &ACKnames[ap->or_nami], mp); + } + } + else { + setsymbolnum(mp->relodata, N_ABS); + } + cvlong(&(mp->address)); + cvlong(&(mp->relodata)); + ap++; + } + bh.rtsize = (char *) mtp - (char *) MACHtrelo; + bh.rdsize = (char *) mdp - (char *) MACHdrelo; + writef(MACHtrelo, 1, bh.rtsize); + writef(MACHdrelo, 1, bh.rdsize); + free(ACKrelo); + free(MACHtrelo); + free(MACHdrelo); +} + +long +get(sz) +{ + char buf[10]; + long l = 0; + register char *p = buf + sz; + + read(output,buf,sz); + while (sz--) { + l = (l << 8) | (*--p & 0377); + } + return l; +} + +put(l,sz) + long l; +{ + char buf[10]; + register char *p = buf; + + *p++ = l; + *p++ = l >> 8; + *p++ = l >> 16; + *p++ = l >> 24; + p -= sz; + if (write(output, p, sz) < sz) { + fatal("write error.\n"); + } +} + +patch(ap, an, mp) + register struct outrelo *ap; + register struct outname *an; + register struct machrelo *mp; +{ + int whichsect = (an->on_type & S_TYP) - S_MIN; + long correction = 0; + long where = TOT_HDRSIZE+ap->or_addr; + long X; + long here; + int sz; + + if (!(an->on_type & S_SCT)) { + fprintf(stderr,"funny on_type %x\n", an->on_type); + } + switch(whichsect) { + case TEXTSG: + setsymbolnum(mp->relodata,N_TEXT); + return; + case DATASG: + correction = outsect[ROMSG].os_size + outsect[TEXTSG].os_size; + setsymbolnum(mp->relodata,N_DATA); + break; + case ROMSG: + correction = outsect[TEXTSG].os_size; + setsymbolnum(mp->relodata,N_TEXT); + break; + case BSSSG: + correction = outsect[ROMSG].os_size + outsect[TEXTSG].os_size+ + outsect[DATASG].os_size; + setsymbolnum(mp->relodata,N_BSS); + break; + default: + assert(0); + } + + switch(ap->or_sect - S_MIN) { + case DATASG: + where += outsect[ROMSG].os_size; + case ROMSG: + where += outsect[TEXTSG].os_size; + case TEXTSG: + break; + default: + assert(0); + } + here = lseek(output, 0L, 1); + lseek(output, where, 0); + sz = ap->or_type & RELSZ; + X = get(sz) + correction; + lseek(output, where, 0); + put(X,sz); + lseek(output, here, 0); +} + +cvlong(l) + long *l; +{ + long x = *l; + char *p = (char *) l; + + *p++ = x; + *p++ = x >> 8; + *p++ = x >> 16; + *p++ = x >> 24; +} + +int +is_rest_local(A, i) + register int i; + register struct outname *A; +{ + while (i--) { + if (A->on_type & S_EXT) return 0; + A++; + } + return 1; +} + +emit_symtab() +{ + register unsigned short i = outhead.oh_nname; + register struct outname *A; + struct sym *MACHnames; + register struct sym *M; + extern char *malloc(), *calloc(); + char *chars; + long offX = OFF_CHAR(outhead) - 4; + + if (!(A = ACKnames)) { + if (!(A = (struct outname *) + calloc(i, sizeof(struct outname)))) { + fatal("No memory.\n"); + } + rd_name(A, outhead.oh_nname); + } + if (!(M = (struct sym *) calloc(i, sizeof(struct sym)))) { + fatal("No memory.\n"); + } + MACHnames = M; + ACKnames = A; + for (; i; i--, A++) { + M->value = A->on_valu; + if (A->on_type & S_SCT || + (A->on_type & S_ETC) == S_FIL) { + static int rest_local; + if (! unresolved || rest_local || (rest_local = is_rest_local(A, i))) { + outhead.oh_nname--; + continue; + } + } + if (A->on_type & S_COM) { + M->type = N_UNDF | N_EXT; + } + else switch(A->on_type & S_TYP) { + case S_UND: + switch(A->on_type & S_ETC) { + default: + M->type = N_UNDF; + break; + case S_MOD: + M->type = N_FN; + break; + case S_LIN: + M->type = N_ABS; + break; + } + break; + case S_ABS: + M->type = N_ABS; + break; + case S_MIN + TEXTSG: + M->type = N_TEXT; + break; + case S_MIN + ROMSG: + if (unresolved) { + M->value += outsect[TEXTSG].os_size; + } + M->type = (rom_in_data ? N_DATA : N_TEXT); + break; + case S_MIN + DATASG: + if (unresolved) { + M->value += outsect[TEXTSG].os_size + + outsect[ROMSG].os_size; + } + M->type = N_DATA; + break; + case S_MIN + BSSSG: + if (unresolved) { + M->value += outsect[TEXTSG].os_size + + outsect[ROMSG].os_size + + outsect[DATASG].os_size; + } + M->type = N_BSS; + break; + case S_MIN + LSECT: + M->type = N_BSS; + break; + default: + fprintf(stderr,"warning: unknown s_type: %d\n", + A->on_type & S_TYP); + } + if (A->on_type & S_EXT) M->type |= N_EXT; + M->name = A->on_foff; + M++; + } + M = MACHnames; + for (i = outhead.oh_nname; i; i--, M++) { + if (M->name) { + M->name -= offX; + } + else M->name = outhead.oh_nchar + 3; /* pointer to nullbyte */ + cvlong(&(M->name)); + cvlong(&(M->value)); + } + writef(MACHnames, sizeof(struct sym), (long) outhead.oh_nname); + free(MACHnames); + free(ACKnames); + if ((unsigned) outhead.oh_nchar != outhead.oh_nchar || + !( chars = malloc((unsigned) outhead.oh_nchar))) { + fatal("No memory\n."); + } + put(outhead.oh_nchar+4,4); + rd_string(chars,outhead.oh_nchar); + writef(chars, 1, outhead.oh_nchar); + free(chars); +} + +/* 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"); } -- 2.34.1