1 /* $Id: cv.c,v 1.5 1994/06/24 13:08:25 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".
38 #define ASSERT(x) switch (2) { case 0: case (x): ; }
41 * Header and section table of new format object file.
43 struct outhead outhead;
44 struct outsect outsect[S_MAX];
47 int outputfile_created;
55 #define writef(a, b, c) fwrite((a), (b), (int)(c), output)
57 /* Output file definitions and such */
62 #define TOT_HDRSIZE (sizeof(struct bhdr))
84 register struct outsect *pa, *pb;
86 /* return 1 if pa follows pb */
88 return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
105 if ( argc>1 && argv[1][0]=='-' ) {
110 case 3: if ((output = fopen(argv[2], "w")) == (FILE *)0)
111 fatal("Can't write %s.\n", argv[2]);
112 output_file = argv[2];
113 outputfile_created = 1;
114 if (! rd_open(argv[1]))
115 fatal("Can't read %s.\n", argv[1]);
117 default:fatal("Usage: %s <ACK object> <Mantra object>.\n", argv[0]);
120 if (BADMAGIC(outhead))
121 fatal("Not an ack object file.\n");
122 if (outhead.oh_flags & HF_LINK)
123 fatal("Contains unresolved references.\n");
124 if (outhead.oh_nrelo > 0)
125 fprintf(stderr, "Warning: relocation information present.\n");
126 if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
127 fatal("Input file must have %d sections, not %ld\n",
128 NSECT,outhead.oh_nsect) ;
129 rd_sect(outsect, outhead.oh_nsect);
131 if ( outsect[TEXTSG].os_base != ENTRY)
132 fatal("text must start at %d not at 0x%lx\n", ENTRY,
133 outsect[TEXTSG].os_base) ;
134 if ( outsect[BSSSG].os_flen != 0 )
135 fatal("bss space contains initialized data\n") ;
136 if ( ! follows(&outsect[BSSSG], &outsect[DATASG]))
137 fatal("bss segment must follow data segment\n") ;
138 if ( outsect[ROMSG].os_lign == 0x8000 ) {
139 /* 410 file with ROMSG in data space */
140 if ( ! follows(&outsect[DATASG], &outsect[ROMSG]))
141 fatal("data segment must follow rom\n") ;
144 textsize= outsect[TEXTSG].os_size ;
145 datasize= outsect[BSSSG].os_base - outsect[ROMSG].os_base ;
146 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
147 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
149 if ( outsect[DATASG].os_lign == 0x8000 ) {
150 /* 410 file with ROMSG in instruction space */
151 if ( ! follows(&outsect[ROMSG], &outsect[TEXTSG]))
152 fatal("rom segment must follow text\n") ;
155 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
156 textsize= outsect[TEXTSG].os_size + outsect[ROMSG].os_size ;
157 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
158 datasize= outsect[DATASG].os_size ;
161 if ( ! follows(&outsect[ROMSG], &outsect[TEXTSG]))
162 fatal("rom segment must follow text\n") ;
163 if ( ! follows(&outsect[DATASG], &outsect[ROMSG]))
164 fatal("data segment must follow rom\n") ;
167 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
168 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
169 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
170 textsize= outsect[TEXTSG].os_size ;
171 datasize= outsect[ROMSG].os_size + outsect[DATASG].os_size ;
173 bsssize = outsect[BSSSG].os_size;
174 if ( outhead.oh_nsect==NSECT ) {
175 if ( ! follows(&outsect[LSECT], &outsect[BSSSG]))
176 fatal("end segment must follow bss\n") ;
177 if ( outsect[LSECT].os_size != 0 )
178 fatal("end segment must be empty\n") ;
189 fseek(output,(long) TOT_HDRSIZE,0);
190 emits(&outsect[TEXTSG]) ;
191 emits(&outsect[ROMSG]) ;
192 emits(&outsect[DATASG]) ;
193 symstart = ftell(output);
195 bh.ssize = ftell(output) - symstart;
198 if ( ferror(output) ) {
199 fatal("output write error\n") ;
201 if ( outputfile_created ) chmod(argv[2],0755);
206 * Transfer the emitted byted from one file to another.
208 emits(section) struct outsect *section ; {
212 rd_outsect(section - outsect);
213 if (!(p = calloc(section->os_size, 1))) {
214 fatal("No memory.\n");
216 rd_emit(p, section->os_flen);
217 writef(p, 1, section->os_size);
223 struct outname *ACK_names;
224 register unsigned short i;
225 register struct outname *A;
228 extern char *malloc(), *calloc();
230 long off = OFF_CHAR(outhead);
233 if ((unsigned) outhead.oh_nchar != outhead.oh_nchar ||
234 !( chars = malloc((unsigned) outhead.oh_nchar))) {
235 fatal("No memory\n.");
237 rd_string(chars,outhead.oh_nchar);
238 if ((unsigned) outhead.oh_nname != outhead.oh_nname ||
239 !(A = (struct outname *)
240 calloc(outhead.oh_nname, sizeof(struct outname)))) {
241 fatal("No memory.\n");
244 rd_name(ACK_names, outhead.oh_nname);
245 for (i = 0; i < outhead.oh_nname; i++, A++) {
246 if ((A->on_type & S_TYP) >= S_MIN + LSECT ||
247 A->on_foff == 0) continue;
248 switch(A->on_type & S_TYP) {
259 x = (rom_in_data ? N_DATA : N_TEXT);
268 fprintf(stderr,"warning: unknown s_type: %d\n",
271 if (A->on_type & S_EXT) x |= N_EXT;
274 write_long(A->on_valu);
275 l = A->on_foff - off;
276 if (l < 0 || l >= outhead.oh_nchar) {
277 fatal("bad on_off: %ld\n",l);
290 /* write long "l" in 68000 order
293 putc((int) (l >> 24), output);
294 putc((int) (l >> 16), output);
295 putc((int) (l >> 8), output);
296 putc((int) l, output);
300 register struct bhdr *h;
302 write_long(h->fmagic);
303 write_long(h->tsize);
304 write_long(h->dsize);
305 write_long(h->bsize);
306 write_long(h->ssize);
307 write_long(h->rtsize);
308 write_long(h->rdsize);
309 write_long(h->entry);
316 fprintf(stderr,"%s: ",program) ;
317 fprintf(stderr, s, a1, a2);
318 if (outputfile_created)
323 rd_fatal() { fatal("read error.\n"); }