1 /* $Id: cv.c,v 1.3 1994/06/24 13:09:18 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 ST-Minix object format.
16 struct outhead outhead;
17 struct outsect outsect[S_MAX];
27 int outputfile_created;
31 /* Output file definitions and such */
55 stack = 0x00010000L - (mh[3] + mh[4]);
56 if ((mh[0] & 0x00200000L) == 0) /* not SEPARATE */
61 stack = chmem(chmemstr, stack);
62 printf("%ld bytes assigned to stack+malloc area\n", stack);
63 mh[6] = stack + (mh[3] + mh[4]);
64 if ((mh[0] & 0x00200000L) == 0) /* not SEPARATE */
67 for (i = 0; i < 8; i++) {
71 if (write(output, (char *) mh, sizeof(mh)) != sizeof(mh))
72 fatal("write error\n");
85 register struct outsect *pa, *pb;
87 /* return 1 if pa follows pb */
89 return pa->os_base == align(pb->os_base+pb->os_size, pa->os_lign);
109 case 3: if ((output = creat(argv[2], 0644)) < 0)
110 fatal("Can't write %s.\n", argv[2]);
111 output_file = argv[2];
112 outputfile_created = 1;
113 if (! rd_open(argv[1]))
114 fatal("Can't read %s.\n", argv[1]);
116 default:fatal("Usage: %s [+-= amount] <ACK object> <ST-MINIX object>.\n", argv[0]);
119 if (BADMAGIC(outhead))
120 fatal("Not an ack object file.\n");
121 if (outhead.oh_flags & HF_LINK) {
123 fatal("Contains unresolved references.\n");
125 if ( outhead.oh_nsect!=LSECT && outhead.oh_nsect!=NSECT )
126 fatal("Input file must have %d sections, not %ld\n",
127 NSECT,outhead.oh_nsect) ;
128 rd_sect(outsect, outhead.oh_nsect);
130 if ( outsect[BSSSG].os_flen != 0 )
131 fatal("bss space contains initialized data\n") ;
132 if (! follows(&outsect[BSSSG], &outsect[DATASG]))
133 fatal("bss segment must follow data segment\n") ;
134 textsize= (outsect[DATASG].os_base - outsect[TEXTSG].os_base);
135 if (! follows(&outsect[ROMSG],&outsect[TEXTSG]))
136 fatal("rom segment must follow text\n") ;
137 if (! follows(&outsect[DATASG],&outsect[ROMSG]))
138 fatal("data segment must follow rom\n") ;
139 outsect[TEXTSG].os_size = outsect[ROMSG].os_base - outsect[TEXTSG].os_base;
140 outsect[ROMSG].os_size = outsect[DATASG].os_base - outsect[ROMSG].os_base;
141 outsect[DATASG].os_size = outsect[BSSSG].os_base - outsect[DATASG].os_base;
142 datasize= outsect[DATASG].os_size ;
143 bsssize = outsect[BSSSG].os_size;
144 if ( outhead.oh_nsect==NSECT ) {
145 if (! follows(&outsect[LSECT],&outsect[BSSSG]))
146 fatal("end segment must follow bss\n") ;
147 if ( outsect[LSECT].os_size != 0 )
148 fatal("end segment must be empty\n") ;
152 emits(&outsect[TEXTSG]) ;
153 emits(&outsect[ROMSG]) ;
154 emits(&outsect[DATASG]) ;
156 if ( outputfile_created) chmod(argv[2],0755);
161 * Transfer the emitted byted from one file to another.
163 emits(section) struct outsect *section ; {
165 char *calloc(), *malloc();
166 long sz = section->os_flen;
168 rd_outsect(section - outsect);
170 unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
171 if (!(p = malloc(0x4000))) {
172 fatal("No memory.\n");
174 rd_emit(p, (long) i);
175 if (write(output, p, (int)i) < i) {
176 fatal("write error.\n");
182 sz = section->os_size - section->os_flen;
184 if (!(p = calloc(0x4000, 1))) {
185 fatal("No memory.\n");
188 unsigned int i = (sz >= 0x4000 ? 0x4000 : sz);
189 if (write(output, p, (int)i) < i) {
190 fatal("write error.\n");
200 register struct outrelo *a, *b;
202 if (a->or_sect < b->or_sect) return -1;
203 if (a->or_sect > b->or_sect) return 1;
204 if (a->or_addr < b->or_addr) return -1;
205 if (a->or_addr > b->or_addr) return 1;
211 struct outrelo *ACKrelo;
212 register struct outrelo *ap;
213 unsigned int cnt = outhead.oh_nrelo;
214 long last, curr, base;
219 ACKrelo = ap = (struct outrelo *) calloc(cnt, sizeof(struct outrelo));
220 bp = b = malloc(4 + cnt);
222 fatal("No memory.\n");
225 qsort((char *) ap, (int) cnt, sizeof(struct outrelo), compare);
227 * read relocation, modify to GEMDOS format, and write.
228 * Only longs can be relocated.
230 * The GEMDOS format starts with a long L: the offset to the
231 * beginning of text for the first long to be relocated.
232 * If L==0 then no relocations have to be made.
234 * The long is followed by zero or more bytes. Each byte B is
235 * processed separately, in one of the following ways:
240 * no relocation, but add 254 to the current offset
242 * B is added to the current offset and the long addressed
243 * is relocated. Note that 00000010 means 1 word distance.
250 for (sect = S_MIN; sect <= S_MIN+2; sect++) {
251 base = outsect[sect-S_MIN].os_base;
252 for (;cnt > 0 && ap->or_sect == sect; ap++, cnt--) {
253 if (ap->or_type & RELPC ||
254 ap->or_nami == outhead.oh_nname) {
257 assert(ap->or_type & RELO4);
258 curr = base + ap->or_addr;
262 *((long *) b) = curr;
266 while (curr - last > 255) {
274 assert(cnt == 0 || ap->or_sect > sect);
277 if (cnt = (b - bp)) {
279 write(output, bp, (int) cnt+1);
281 else write(output, "\0\0\0", 4);
282 free((char *) ACKrelo);
291 register long num, new;
296 fatal("bad chmem amount %s\n", str+1);
299 new = old - num; break;
301 new = old + num; break;
312 char *p = (char *) l;
324 fprintf(stderr,"%s: ",program) ;
325 fprintf(stderr, s, a1, a2);
326 if (outputfile_created)
331 rd_fatal() { fatal("read error.\n"); }