|
@@ -0,0 +1,354 @@
|
|
|
+/*
|
|
|
+ * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
+ *
|
|
|
+ * This product is part of the Amsterdam Compiler Kit.
|
|
|
+ *
|
|
|
+ * Permission to use, sell, duplicate or disclose this software must be
|
|
|
+ * obtained in writing. Requests for such permissions may be sent to
|
|
|
+ *
|
|
|
+ * Dr. Andrew S. Tanenbaum
|
|
|
+ * Wiskundig Seminarium
|
|
|
+ * Vrije Universiteit
|
|
|
+ * Postbox 7161
|
|
|
+ * 1007 MC Amsterdam
|
|
|
+ * The Netherlands
|
|
|
+ *
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Convert Mantra object format to ACK object format
|
|
|
+ */
|
|
|
+#include <stdio.h>
|
|
|
+#include <out.h>
|
|
|
+
|
|
|
+#define FMAGIC 0407
|
|
|
+#define REG 06
|
|
|
+
|
|
|
+#define RTEXT 00
|
|
|
+#define RDATA 01
|
|
|
+#define RBSS 02
|
|
|
+#define REXT 03
|
|
|
+
|
|
|
+#define RBYTE 00
|
|
|
+#define RWORD 01
|
|
|
+#define RLONG 02
|
|
|
+
|
|
|
+struct bhdr {
|
|
|
+ long fmagic;
|
|
|
+ long tsize;
|
|
|
+ long dsize;
|
|
|
+ long bsize;
|
|
|
+ long ssize;
|
|
|
+ long rtsize;
|
|
|
+ long rdsize;
|
|
|
+ long entry;
|
|
|
+};
|
|
|
+
|
|
|
+struct reloc {
|
|
|
+ char x;
|
|
|
+#define setseg(p,s) (p->x = (p->x & ~03) | s)
|
|
|
+#define setsiz(p,s) (p->x = (p->x & ~014) | (s << 2))
|
|
|
+#define setdis(p,s) (p->x = (p->x & ~020) | (s << 4))
|
|
|
+#define getseg(p) (p->x&03)
|
|
|
+#define getsiz(p) ((p->x >> 2) & 03)
|
|
|
+#define getdis(p) ((p->x >> 4) & 01)
|
|
|
+ char relpad2;
|
|
|
+ short rsymbol;
|
|
|
+ long rpos;
|
|
|
+};
|
|
|
+
|
|
|
+#define N_UNDF 0
|
|
|
+#define N_ABS 01
|
|
|
+#define N_TEXT 02
|
|
|
+#define N_DATA 03
|
|
|
+#define N_BSS 04
|
|
|
+#define N_TYPE 037
|
|
|
+#define N_REG 024
|
|
|
+#define N_FN 037
|
|
|
+#define N_EXT 040
|
|
|
+
|
|
|
+#define ASSERT(x) switch (2) { case 0: case (x): ; }
|
|
|
+
|
|
|
+/*
|
|
|
+ * Header and section table of new format object file.
|
|
|
+ */
|
|
|
+struct outhead outhead;
|
|
|
+struct outsect outsect[4];
|
|
|
+#define TEXTSG 0
|
|
|
+#define ROMSG 1
|
|
|
+#define DATASG 2
|
|
|
+#define BSSSG 3
|
|
|
+
|
|
|
+char *output_file;
|
|
|
+
|
|
|
+char *program ;
|
|
|
+
|
|
|
+char flag ;
|
|
|
+
|
|
|
+#define readf(a, b, c) fread((a), (b), (int)(c), input)
|
|
|
+
|
|
|
+/* Output file definitions and such */
|
|
|
+
|
|
|
+struct bhdr bh;
|
|
|
+
|
|
|
+#define TOT_HDRSIZE (sizeof(struct bhdr))
|
|
|
+
|
|
|
+FILE *input;
|
|
|
+
|
|
|
+struct outrelo *orelo = 0;
|
|
|
+struct outname *oname = 0;
|
|
|
+char *strings = 0;
|
|
|
+char *txt = 0;
|
|
|
+char *data = 0;
|
|
|
+
|
|
|
+main(argc, argv)
|
|
|
+ int argc;
|
|
|
+ char *argv[];
|
|
|
+{
|
|
|
+ register struct outsect *p;
|
|
|
+ char *malloc();
|
|
|
+
|
|
|
+ input = stdin;
|
|
|
+ program= argv[0] ;
|
|
|
+ if ( argc>1 && argv[1][0]=='-' ) {
|
|
|
+ flag=argv[1][1] ;
|
|
|
+ argc-- ; argv++ ;
|
|
|
+ }
|
|
|
+ switch (argc) {
|
|
|
+ case 3: if (! wr_open(argv[2]))
|
|
|
+ fatal("Can't write %s.\n", argv[2]);
|
|
|
+ output_file = argv[2];
|
|
|
+ if ((input = fopen(argv[1], "r")) == (FILE *)0)
|
|
|
+ fatal("Can't read %s.\n", argv[1]);
|
|
|
+ break;
|
|
|
+ default:fatal("Usage: %s <Mantra object> <ACK object>.\n", argv[0]);
|
|
|
+ }
|
|
|
+ if (! readf(&bh, sizeof(struct bhdr), 1)) rd_fatal();
|
|
|
+ if (bh.fmagic != FMAGIC) fatal("bad magic number\n");
|
|
|
+ outhead.oh_magic = O_MAGIC;
|
|
|
+ outhead.oh_stamp = 0;
|
|
|
+ outhead.oh_nsect = 4;
|
|
|
+ outhead.oh_nrelo = (bh.rtsize + bh.rdsize) / sizeof(struct reloc);
|
|
|
+ outhead.oh_flags = outhead.oh_nrelo ? HF_LINK : 0;
|
|
|
+ outhead.oh_nemit = bh.tsize + bh.dsize;
|
|
|
+ strings = malloc((unsigned) bh.ssize + 20);
|
|
|
+ orelo = (struct outrelo *)
|
|
|
+ malloc(outhead.oh_nrelo * sizeof(struct outrelo));
|
|
|
+ oname = (struct outname *)
|
|
|
+ malloc((unsigned) (bh.ssize / 6 + 3) * sizeof (struct outname));
|
|
|
+ txt = malloc(bh.tsize);
|
|
|
+ data = malloc(bh.dsize);
|
|
|
+ if (!strings || !orelo || !oname || !txt || !data) {
|
|
|
+ fatal("No memory\n");
|
|
|
+ }
|
|
|
+ p = &outsect[TEXTSG];
|
|
|
+ p->os_base = 0; p->os_size = p->os_flen = bh.tsize;
|
|
|
+ p->os_foff = OFF_EMIT(outhead); p->os_lign = 1;
|
|
|
+ p = &outsect[ROMSG];
|
|
|
+ p->os_base = p->os_size = p->os_flen = 0;
|
|
|
+ p->os_foff = OFF_EMIT(outhead) + bh.tsize; p->os_lign = 1;
|
|
|
+ p = &outsect[DATASG];
|
|
|
+ p->os_base = 0; p->os_size = p->os_flen = bh.dsize;
|
|
|
+ p->os_foff = OFF_EMIT(outhead) + bh.tsize; p->os_lign = 1;
|
|
|
+ p = &outsect[BSSSG];
|
|
|
+ p->os_base = p->os_flen = 0; p->os_size = bh.bsize;
|
|
|
+ p->os_foff = OFF_EMIT(outhead)+bh.tsize+bh.dsize; p->os_lign = 1;
|
|
|
+
|
|
|
+ if (bh.tsize && ! readf(txt, 1, bh.tsize)) rd_fatal();
|
|
|
+ if (bh.dsize && ! readf(data, 1, bh.dsize)) rd_fatal();
|
|
|
+
|
|
|
+ symtab(oname, strings);
|
|
|
+ relo(orelo, txt, data);
|
|
|
+ wr_ohead(&outhead);
|
|
|
+ wr_sect(outsect, 4);
|
|
|
+ wr_outsect(TEXTSG);
|
|
|
+ wr_emit(txt, bh.tsize);
|
|
|
+ wr_outsect(DATASG);
|
|
|
+ wr_emit(data,bh.dsize);
|
|
|
+ wr_relo(orelo, outhead.oh_nrelo);
|
|
|
+ wr_name(oname, outhead.oh_nname);
|
|
|
+ wr_string(strings, outhead.oh_nchar);
|
|
|
+ wr_close();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+symtab(name, string)
|
|
|
+ struct outname *name;
|
|
|
+ char *string;
|
|
|
+{
|
|
|
+ register struct outname *oname = name;
|
|
|
+ register char *strings = string;
|
|
|
+ register int c;
|
|
|
+ unsigned nnames = 3;
|
|
|
+ register long ssize = bh.ssize;
|
|
|
+ register char *b;
|
|
|
+
|
|
|
+ oname->on_valu = 0; oname->on_foff = 0; oname->on_desc = 0;
|
|
|
+ oname->on_type = (S_MIN+TEXTSG) | S_SCT;
|
|
|
+ b = ".text"; while (*strings++ = *b) b++;
|
|
|
+ oname++;
|
|
|
+ oname->on_valu = 0; oname->on_foff = strings - string; oname->on_desc = 0;
|
|
|
+ oname->on_type = (S_MIN+DATASG) | S_SCT;
|
|
|
+ b = ".data"; while (*strings++ = *b) b++;
|
|
|
+ oname++;
|
|
|
+ oname->on_valu = 0; oname->on_foff = strings - string; oname->on_desc = 0;
|
|
|
+ oname->on_type = (S_MIN+BSSSG) | S_SCT;
|
|
|
+ b = ".bss"; while (*strings++ = *b) b++;
|
|
|
+ oname++;
|
|
|
+ while (ssize > 0) {
|
|
|
+ c = getc(input);
|
|
|
+ getc(input);
|
|
|
+ oname->on_valu = getw(input);
|
|
|
+ ssize -= 6;
|
|
|
+ switch(c & ~N_EXT) {
|
|
|
+ case N_ABS:
|
|
|
+ oname->on_type = S_ABS;
|
|
|
+ break;
|
|
|
+ case N_TEXT:
|
|
|
+ oname->on_type = S_MIN + TEXTSG;
|
|
|
+ break;
|
|
|
+ case N_DATA:
|
|
|
+ oname->on_type = S_MIN + DATASG;
|
|
|
+ oname->on_valu -= bh.tsize;
|
|
|
+ break;
|
|
|
+ case N_BSS:
|
|
|
+ oname->on_type = S_MIN + BSSSG;
|
|
|
+ oname->on_valu -= bh.tsize + bh.dsize;
|
|
|
+ break;
|
|
|
+ case N_UNDF:
|
|
|
+ if (! oname->on_valu) {
|
|
|
+ oname->on_type = S_UND;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ oname->on_type = (S_MIN + BSSSG) | S_COM;
|
|
|
+ break;
|
|
|
+ case REG:
|
|
|
+ case N_REG:
|
|
|
+ case N_FN:
|
|
|
+ while (ssize > 0 && (getc(input) > 0))
|
|
|
+ ssize--;
|
|
|
+ continue;
|
|
|
+ default:
|
|
|
+ fatal("Illegal type field %d in namelist\n", c);
|
|
|
+ }
|
|
|
+ if (c & N_EXT) oname->on_type |= S_EXT;
|
|
|
+ oname->on_desc = 0;
|
|
|
+ oname->on_foff = strings - string;
|
|
|
+ nnames++;
|
|
|
+ while (ssize > 0 && (c = getc(input)) > 0) {
|
|
|
+ *strings++ = c;
|
|
|
+ ssize--;
|
|
|
+ }
|
|
|
+ ssize--;
|
|
|
+ *strings++ = c;
|
|
|
+ oname++;
|
|
|
+ }
|
|
|
+ outhead.oh_nname = nnames;
|
|
|
+ outhead.oh_nchar = strings - string;
|
|
|
+ oname = name;
|
|
|
+ ssize = OFF_CHAR(outhead);
|
|
|
+ while (nnames--) {
|
|
|
+ oname->on_foff += ssize;
|
|
|
+ oname++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+long
|
|
|
+get4(c)
|
|
|
+ register char *c;
|
|
|
+{
|
|
|
+ register long l = (long) (*c++ & 0377) << 24;
|
|
|
+
|
|
|
+ l |= (long) (*c++ & 0377) << 16;
|
|
|
+ l |= (long) (*c++ & 0377) << 8;
|
|
|
+ l |= (long) (*c++ & 0377);
|
|
|
+ return l;
|
|
|
+}
|
|
|
+
|
|
|
+put4(l, c)
|
|
|
+ register char *c;
|
|
|
+ register long l;
|
|
|
+{
|
|
|
+ *c++ = (l >> 24);
|
|
|
+ *c++ = (l >> 16);
|
|
|
+ *c++ = (l >> 8);
|
|
|
+ *c = l;
|
|
|
+}
|
|
|
+
|
|
|
+relo(orelo, txt, data)
|
|
|
+ struct outrelo *orelo;
|
|
|
+ char *txt, *data;
|
|
|
+{
|
|
|
+ register struct outrelo *relo = orelo;
|
|
|
+ register relocnt = outhead.oh_nrelo;
|
|
|
+ struct reloc rel;
|
|
|
+ register struct reloc *relp = &rel;
|
|
|
+ int ndat = bh.rdsize / sizeof(struct reloc);
|
|
|
+
|
|
|
+ while (relocnt-- > 0) {
|
|
|
+ readf(relp, sizeof(struct reloc), 1);
|
|
|
+ relo->or_sect = (relocnt >= ndat) ? S_MIN + TEXTSG :
|
|
|
+ S_MIN + DATASG;
|
|
|
+ relo->or_addr = relp->rpos;
|
|
|
+ relo->or_nami = relp->rsymbol + 3;
|
|
|
+ switch(getseg(relp)) {
|
|
|
+ case RTEXT:
|
|
|
+ relo->or_nami = 0;
|
|
|
+ break;
|
|
|
+ case RDATA:
|
|
|
+ relo->or_nami = 1;
|
|
|
+ break;
|
|
|
+ case RBSS:
|
|
|
+ relo->or_nami = 2;
|
|
|
+ break;
|
|
|
+ case REXT:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ fatal("Error 1 in relocation\n");
|
|
|
+ }
|
|
|
+ switch(getsiz(relp)) {
|
|
|
+ case RBYTE:
|
|
|
+ relo->or_type = RELO1|RELBR|RELWR;
|
|
|
+ break;
|
|
|
+ case RWORD:
|
|
|
+ relo->or_type = RELO2|RELBR|RELWR;
|
|
|
+ break;
|
|
|
+ case RLONG: {
|
|
|
+ register char *sct = (relocnt >= ndat ? txt : data) +
|
|
|
+ relo->or_addr;
|
|
|
+ long x;
|
|
|
+
|
|
|
+ relo->or_type = RELO4|RELBR|RELWR;
|
|
|
+ switch((oname + relo->or_nami)->on_type & S_TYP) {
|
|
|
+ case (S_MIN+DATASG):
|
|
|
+ x = get4(sct) - bh.tsize;
|
|
|
+
|
|
|
+ put4(x, sct);
|
|
|
+ break;
|
|
|
+ case (S_MIN+BSSSG):
|
|
|
+ if (! ((oname+relo->or_nami)->on_type & S_COM))
|
|
|
+ x = get4(sct) - (bh.tsize + bh.dsize);
|
|
|
+ put4(x, sct);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ fatal("Error 2 in relocation\n");
|
|
|
+ }
|
|
|
+ if (getdis(relp)) relo->or_type |= RELPC;
|
|
|
+ relo++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* VARARGS1 */
|
|
|
+fatal(s, a1, a2)
|
|
|
+ char *s;
|
|
|
+{
|
|
|
+ fprintf(stderr,"%s: ",program) ;
|
|
|
+ fprintf(stderr, s, a1, a2);
|
|
|
+ unlink(output_file);
|
|
|
+ exit(-1);
|
|
|
+}
|
|
|
+
|
|
|
+wr_fatal() { fatal("Write error\n"); }
|
|
|
+rd_fatal() { fatal("Read error\n"); }
|