1 /* $Id: Xcv.c,v 1.4 1994/06/24 13:08:21 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
9 * Convert Mantra object format to ACK object format
39 #define setseg(p,s) (p->x = (p->x & ~03) | s)
40 #define setsiz(p,s) (p->x = (p->x & ~014) | (s << 2))
41 #define setdis(p,s) (p->x = (p->x & ~020) | (s << 4))
42 #define getseg(p) (p->x&03)
43 #define getsiz(p) ((p->x >> 2) & 03)
44 #define getdis(p) ((p->x >> 4) & 01)
60 #define ASSERT(x) switch (2) { case 0: case (x): ; }
63 * Header and section table of new format object file.
65 struct outhead outhead;
66 struct outsect outsect[4];
78 #define readf(a, b, c) fread((a), (b), (int)(c), input)
80 /* Output file definitions and such */
84 #define TOT_HDRSIZE (sizeof(struct bhdr))
88 struct outrelo *orelo = 0;
89 struct outname *oname = 0;
98 register struct outsect *p;
103 if ( argc>1 && argv[1][0]=='-' ) {
108 case 3: if (! wr_open(argv[2]))
109 fatal("Can't write %s.\n", argv[2]);
110 output_file = argv[2];
111 if ((input = fopen(argv[1], "r")) == (FILE *)0)
112 fatal("Can't read %s.\n", argv[1]);
114 default:fatal("Usage: %s <Mantra object> <ACK object>.\n", argv[0]);
116 if (! readf(&bh, sizeof(struct bhdr), 1)) rd_fatal();
117 if (bh.fmagic != FMAGIC) fatal("bad magic number\n");
118 outhead.oh_magic = O_MAGIC;
119 outhead.oh_stamp = 0;
120 outhead.oh_nsect = 4;
121 outhead.oh_nrelo = (bh.rtsize + bh.rdsize) / sizeof(struct reloc);
122 outhead.oh_flags = outhead.oh_nrelo ? HF_LINK : 0;
123 outhead.oh_nemit = bh.tsize + bh.dsize;
124 strings = malloc((unsigned) bh.ssize + 20);
125 orelo = (struct outrelo *)
126 malloc(outhead.oh_nrelo * sizeof(struct outrelo));
127 oname = (struct outname *)
128 malloc((unsigned) (bh.ssize / 6 + 3) * sizeof (struct outname));
129 txt = malloc(bh.tsize);
130 data = malloc(bh.dsize);
131 if (!strings || !orelo || !oname || !txt || !data) {
132 fatal("No memory\n");
134 p = &outsect[TEXTSG];
135 p->os_base = 0; p->os_size = p->os_flen = bh.tsize;
136 p->os_foff = OFF_EMIT(outhead); p->os_lign = 1;
138 p->os_base = p->os_size = p->os_flen = 0;
139 p->os_foff = OFF_EMIT(outhead) + bh.tsize; p->os_lign = 1;
140 p = &outsect[DATASG];
141 p->os_base = 0; p->os_size = p->os_flen = bh.dsize;
142 p->os_foff = OFF_EMIT(outhead) + bh.tsize; p->os_lign = 1;
144 p->os_base = p->os_flen = 0; p->os_size = bh.bsize;
145 p->os_foff = OFF_EMIT(outhead)+bh.tsize+bh.dsize; p->os_lign = 1;
147 if (bh.tsize && ! readf(txt, 1, bh.tsize)) rd_fatal();
148 if (bh.dsize && ! readf(data, 1, bh.dsize)) rd_fatal();
150 symtab(oname, strings);
151 relo(orelo, txt, data);
155 wr_emit(txt, bh.tsize);
157 wr_emit(data,bh.dsize);
158 wr_relo(orelo, outhead.oh_nrelo);
159 wr_name(oname, outhead.oh_nname);
160 wr_string(strings, outhead.oh_nchar);
166 struct outname *name;
169 register struct outname *oname = name;
170 register char *strings = string;
173 register long ssize = bh.ssize;
176 oname->on_valu = 0; oname->on_foff = 0; oname->on_desc = 0;
177 oname->on_type = (S_MIN+TEXTSG) | S_SCT;
178 b = ".text"; while (*strings++ = *b) b++;
180 oname->on_valu = 0; oname->on_foff = strings - string; oname->on_desc = 0;
181 oname->on_type = (S_MIN+DATASG) | S_SCT;
182 b = ".data"; while (*strings++ = *b) b++;
184 oname->on_valu = 0; oname->on_foff = strings - string; oname->on_desc = 0;
185 oname->on_type = (S_MIN+BSSSG) | S_SCT;
186 b = ".bss"; while (*strings++ = *b) b++;
191 oname->on_valu = getw(input);
195 oname->on_type = S_ABS;
198 oname->on_type = S_MIN + TEXTSG;
201 oname->on_type = S_MIN + DATASG;
202 oname->on_valu -= bh.tsize;
205 oname->on_type = S_MIN + BSSSG;
206 oname->on_valu -= bh.tsize + bh.dsize;
209 if (! oname->on_valu) {
210 oname->on_type = S_UND;
213 oname->on_type = (S_MIN + BSSSG) | S_COM;
218 while (ssize > 0 && (getc(input) > 0))
222 fatal("Illegal type field %d in namelist\n", c);
224 if (c & N_EXT) oname->on_type |= S_EXT;
226 oname->on_foff = strings - string;
228 while (ssize > 0 && (c = getc(input)) > 0) {
236 outhead.oh_nname = nnames;
237 outhead.oh_nchar = strings - string;
239 ssize = OFF_CHAR(outhead);
241 oname->on_foff += ssize;
250 register long l = (long) (*c++ & 0377) << 24;
252 l |= (long) (*c++ & 0377) << 16;
253 l |= (long) (*c++ & 0377) << 8;
254 l |= (long) (*c++ & 0377);
268 relo(orelo, txt, data)
269 struct outrelo *orelo;
272 register struct outrelo *relo = orelo;
273 register relocnt = outhead.oh_nrelo;
275 register struct reloc *relp = &rel;
276 int ndat = bh.rdsize / sizeof(struct reloc);
278 while (relocnt-- > 0) {
279 readf(relp, sizeof(struct reloc), 1);
280 relo->or_sect = (relocnt >= ndat) ? S_MIN + TEXTSG :
282 relo->or_addr = relp->rpos;
283 relo->or_nami = relp->rsymbol + 3;
284 switch(getseg(relp)) {
297 fatal("Error 1 in relocation\n");
299 switch(getsiz(relp)) {
301 relo->or_type = RELO1|RELBR|RELWR;
304 relo->or_type = RELO2|RELBR|RELWR;
307 register char *sct = (relocnt >= ndat ? txt : data) +
311 relo->or_type = RELO4|RELBR|RELWR;
312 switch((oname + relo->or_nami)->on_type & S_TYP) {
314 x = get4(sct) - bh.tsize;
319 if (! ((oname+relo->or_nami)->on_type & S_COM))
320 x = get4(sct) - (bh.tsize + bh.dsize);
326 fatal("Error 2 in relocation\n");
328 if (getdis(relp)) relo->or_type |= RELPC;
337 fprintf(stderr,"%s: ",program) ;
338 fprintf(stderr, s, a1, a2);
343 wr_fatal() { fatal("Write error\n"); }
344 rd_fatal() { fatal("Read error\n"); }