123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- */
- /*
- * 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"); }
|