1 /* $Id: cv.c,v 1.21 1994/06/24 13:34:22 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 ACK a.out file to SUN3 object format.
20 char *calloc(), *malloc();
23 #define OMAGIC 0407 /* old-fashioned */
24 #define NMAGIC 0410 /* text write protexted */
25 #define ZMAGIC 0413 /* demand paging */
43 #define setpcrel(X,f) (X |= (f<<7))
44 #define setsymbolnum(X,n) (X = (X & 0377) | ((long)n << 8))
45 #define setextern(X,f) (X |= (f << 4))
46 #define setlength(X,l) (X = (X & ~0x60)|((long) l << 5))
65 * Header and section table of new format object file.
67 struct outhead outhead;
68 struct outsect outsect[S_MAX];
71 int outputfile_created;
80 /* Output file definitions and such */
85 #define TOT_HDRSIZE (sizeof(struct bhdr))
112 register struct outsect *pa, *pb;
114 /* return 1 if pa follows pb */
116 return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
126 if ( argc>1 && argv[1][0]=='-' ) {
128 if (flag == 'u') unresolved++;
132 case 3: if ((output = creat(argv[2], 0644)) < 0 ||
133 (close(output), output = open(argv[2],2)) < 0)
134 fatal("Can't write %s.\n", argv[2]);
135 output_file = argv[2];
136 outputfile_created = 1;
137 if (! rd_open(argv[1]))
138 fatal("Can't read %s.\n", argv[1]);
140 default:fatal("Usage: %s [-u] <ACK object> <Sun object>.\n", program);
143 if (BADMAGIC(outhead))
144 fatal("Not an ack object file.\n");
145 if (outhead.oh_flags & HF_LINK) {
147 fprintf(stderr,"Warning: contains unresolved references.\n");
151 else if (outhead.oh_nrelo > 0 && !unresolved)
152 fprintf(stderr, "Warning: relocation information present.\n");
153 if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
154 fatal("Input file must have %d sections, not %ld\n",
155 NSECT,outhead.oh_nsect) ;
156 rd_sect(outsect, outhead.oh_nsect);
158 if ( outsect[BSSSG].os_flen != 0 )
159 fatal("bss space contains initialized data\n") ;
160 if ( !unresolved && ! follows(&outsect[BSSSG], &outsect[DATASG]))
161 fatal("bss segment must follow data segment\n") ;
162 if ( outsect[ROMSG].os_lign == 0x20000 ) {
163 /* 410/413 file with ROMSG in data space */
166 textsize= outsect[TEXTSG].os_size ;
167 datasize= outsect[BSSSG].os_base - outsect[ROMSG].os_base ;
168 if (! follows(&outsect[DATASG], &outsect[ROMSG]))
169 fatal("data segment must follow rom\n") ;
170 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
171 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
173 if ( outsect[DATASG].os_lign == 0x20000 ) {
174 /* 410/413 file with ROMSG in instruction space */
177 textsize= (outsect[ROMSG].os_base - outsect[TEXTSG].os_base) +
178 outsect[ROMSG].os_size ;
179 if (! follows(&outsect[ROMSG],&outsect[TEXTSG]))
180 fatal("rom segment must follow text\n") ;
181 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
182 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
183 datasize= outsect[DATASG].os_size ;
189 textsize= (outsect[DATASG].os_base - outsect[TEXTSG].os_base);
190 if (! follows(&outsect[ROMSG],&outsect[TEXTSG]))
191 fatal("rom segment must follow text\n") ;
192 if (! follows(&outsect[DATASG],&outsect[ROMSG]))
193 fatal("data segment must follow rom\n") ;
194 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
195 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
196 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
199 textsize = outsect[TEXTSG].os_size+outsect[ROMSG].os_size;
201 datasize = outsect[DATASG].os_size;
203 if (outsect[TEXTSG].os_base == TOT_HDRSIZE+ENTRY) {
204 if (magic != NMAGIC) {
205 fatal("illegal alignments.\n");
208 textsize = (textsize + TOT_HDRSIZE + (0x2000 - 1)) & ~(0x2000 - 1);
209 datasize = (datasize + (0x2000 - 1)) & ~(0x2000 - 1);
211 bsssize = outsect[BSSSG].os_size;
212 if ( outhead.oh_nsect==NSECT ) {
213 if (! follows(&outsect[LSECT],&outsect[BSSSG]))
214 fatal("end segment must follow bss\n") ;
215 if ( outsect[LSECT].os_size != 0 )
216 fatal("end segment must be empty\n") ;
219 if (magic != OMAGIC && unresolved) {
220 fatal("unresolved references with wrong magic number\n");
223 if ((magic == ZMAGIC && outsect[TEXTSG].os_base != TOT_HDRSIZE+ENTRY) ||
224 (magic != ZMAGIC && !unresolved && outsect[TEXTSG].os_base != ENTRY)) {
225 fatal("Illegal entry point.\n");
235 if (magic == ZMAGIC) bh.entry = TOT_HDRSIZE+ENTRY;
236 else if (!unresolved) bh.entry = ENTRY;
240 lseek(output,(long) TOT_HDRSIZE,0);
241 emits(&outsect[TEXTSG]) ;
242 if (rom_in_data && magic == ZMAGIC) {
243 lseek(output,textsize,0);
245 emits(&outsect[ROMSG]) ;
246 if (!rom_in_data && magic == ZMAGIC) {
247 lseek(output,textsize,0);
249 emits(&outsect[DATASG]) ;
250 if (magic == ZMAGIC) {
251 lseek(output,textsize + datasize,0);
253 if (unresolved) emit_relo();
255 bh.ssize = outhead.oh_nname * sizeof(struct sym);
257 cvshort(&(bh.machtype));
258 cvshort(&(bh.magic));
264 cvlong(&(bh.rtsize));
265 cvlong(&(bh.rdsize));
266 writef(&bh, 1, (long) TOT_HDRSIZE);
267 if ( outputfile_created && !unresolved ) chmod(argv[2],0755);
278 int i = cnt >= 0x4000 ? 0x4000 : cnt;
281 if (write(output, addr, i) < i) {
282 fatal("write error\n");
289 * Transfer the emitted byted from one file to another.
291 emits(section) struct outsect *section ; {
293 long sz = section->os_flen;
295 rd_outsect(section - outsect);
297 unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
298 if (!(p = malloc(i))) {
299 fatal("No memory.\n");
302 if (write(output, p, i) < i) {
303 fatal("write error.\n");
309 sz = section->os_size - section->os_flen;
311 if (!(p = calloc(0x4000, 1))) {
312 fatal("No memory.\n");
315 unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
316 if (write(output, p, i) < i) {
317 fatal("write error.\n");
325 struct outname *ACKnames;
329 struct outrelo *ACKrelo;
330 struct machrelo *MACHtrelo,*MACHdrelo;
331 register struct outrelo *ap;
332 register struct machrelo *mtp, *mdp;
333 unsigned int cnt = outhead.oh_nrelo;
335 ACKrelo = (struct outrelo *) calloc(cnt, sizeof(struct outrelo));
336 MACHtrelo = (struct machrelo *) calloc(cnt, sizeof(struct machrelo));
337 MACHdrelo = (struct machrelo *) calloc(cnt, sizeof(struct machrelo));
338 ACKnames = (struct outname *) calloc(outhead.oh_nname, sizeof(struct outname));
339 if (!(ap = ACKrelo) || !(mtp = MACHtrelo) || !(mdp = MACHdrelo) ||
341 fatal("No memory.\n");
343 rd_relo(ACKrelo, cnt);
344 rd_name(ACKnames, outhead.oh_nname);
346 register struct machrelo *mp;
348 if (ap->or_sect - S_MIN <= ROMSG) mp = mtp++;
350 setlength(mp->relodata,(ap->or_type&RELSZ) >> 1);
351 setpcrel(mp->relodata,(ap->or_type&RELPC != 0));
352 mp->address = ap->or_addr;
353 if (ap->or_sect == ROMSG+S_MIN) {
354 mp->address += outsect[TEXTSG].os_size;
356 if (ap->or_nami < outhead.oh_nname) {
357 if (ACKnames[ap->or_nami].on_type & S_EXT) {
358 setsymbolnum(mp->relodata, ap->or_nami);
359 setextern(mp->relodata,1);
362 patch(ap, &ACKnames[ap->or_nami], mp);
366 setsymbolnum(mp->relodata, N_ABS);
368 cvlong(&(mp->address));
369 cvlong(&(mp->relodata));
372 bh.rtsize = (char *) mtp - (char *) MACHtrelo;
373 bh.rdsize = (char *) mdp - (char *) MACHdrelo;
374 writef(MACHtrelo, 1, bh.rtsize);
375 writef(MACHdrelo, 1, bh.rdsize);
386 register char *p = buf;
390 l = (l << 8) | (*p++ & 0377);
399 register char *p = buf;
406 if (write(output, p, sz) < sz) {
407 fatal("write error.\n");
412 register struct outrelo *ap;
413 register struct outname *an;
414 register struct machrelo *mp;
416 int whichsect = (an->on_type & S_TYP) - S_MIN;
418 long where = TOT_HDRSIZE+ap->or_addr;
423 if (!(an->on_type & S_SCT)) {
424 fprintf(stderr,"funny on_type %x\n", an->on_type);
428 setsymbolnum(mp->relodata,N_TEXT);
431 correction = outsect[ROMSG].os_size + outsect[TEXTSG].os_size;
432 setsymbolnum(mp->relodata,N_DATA);
435 correction = outsect[TEXTSG].os_size;
436 setsymbolnum(mp->relodata,N_TEXT);
439 correction = outsect[ROMSG].os_size + outsect[TEXTSG].os_size+
440 outsect[DATASG].os_size;
441 setsymbolnum(mp->relodata,N_BSS);
447 switch(ap->or_sect - S_MIN) {
449 where += outsect[ROMSG].os_size;
451 where += outsect[TEXTSG].os_size;
457 here = lseek(output, 0L, 1);
458 lseek(output, where, 0);
459 sz = ap->or_type & RELSZ;
460 X = get(sz) + correction;
461 lseek(output, where, 0);
463 lseek(output, here, 0);
470 char *p = (char *) l;
482 char *p = (char *) s;
491 register struct outname *A;
494 if (A->on_type & S_EXT) return 0;
502 register unsigned short i = outhead.oh_nname;
503 register struct outname *A;
504 struct sym *MACHnames;
505 register struct sym *M;
507 long offX = OFF_CHAR(outhead) - 4;
509 if (!(A = ACKnames)) {
510 if (!(A = (struct outname *)
511 calloc(i, sizeof(struct outname)))) {
512 fatal("No memory.\n");
514 rd_name(A, outhead.oh_nname);
516 if (!(M = (struct sym *) calloc(i, sizeof(struct sym)))) {
517 fatal("No memory.\n");
521 for (; i; i--, A++) {
522 M->value = A->on_valu;
523 M->desc = A->on_desc;
524 if ((A->on_type & S_SCT) ||
525 (A->on_type & S_ETC) == S_FIL) {
526 static int rest_local;
527 if (! unresolved || rest_local || (rest_local = is_rest_local(A, i))) {
532 if (A->on_type & S_STB) {
533 M->type = A->on_type >> 8;
535 else if (A->on_type & S_COM) {
536 M->type = N_UNDF | N_EXT;
538 else switch(A->on_type & S_TYP) {
540 switch(A->on_type & S_ETC) {
560 M->value += outsect[TEXTSG].os_size;
562 M->type = (rom_in_data ? N_DATA : N_TEXT);
566 M->value += outsect[TEXTSG].os_size +
567 outsect[ROMSG].os_size;
573 M->value += outsect[TEXTSG].os_size +
574 outsect[ROMSG].os_size +
575 outsect[DATASG].os_size;
583 fprintf(stderr,"warning: unknown s_type: %d\n",
586 if (A->on_type & S_EXT) M->type |= N_EXT;
587 M->name = A->on_foff;
591 for (i = outhead.oh_nname; i; i--, M++) {
595 else M->name = outhead.oh_nchar + 3; /* pointer to nullbyte */
600 writef(MACHnames, sizeof(struct sym), (long) outhead.oh_nname);
603 if ((unsigned) outhead.oh_nchar != outhead.oh_nchar ||
604 !( chars = malloc((unsigned) outhead.oh_nchar))) {
605 fatal("No memory\n.");
607 put(outhead.oh_nchar+4,4);
608 rd_string(chars,outhead.oh_nchar);
609 writef(chars, 1, outhead.oh_nchar);
617 fprintf(stderr,"%s: ",program) ;
618 fprintf(stderr, s, a1, a2);
619 if (outputfile_created)
624 rd_fatal() { fatal("read error.\n"); }