Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / amiga / stand / bootblock / aout2bb / aout2bb.c
bloba7bf22c1c87867e62eef8abf8f6912ea4a4910b2
1 /* $NetBSD: aout2bb.c,v 1.14 2008/04/28 20:23:13 martin Exp $ */
3 /*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Ignatios Souvatzis.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
34 #endif
36 #include <sys/types.h>
38 #include <err.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
45 #include <sys/mman.h> /* of the machine we're running on */
46 #include <sys/endian.h> /* of the machine we're running on */
48 #define BE32TOH(x) do {(x) = be32toh(x);} while (0)
50 #include <sys/exec_aout.h> /* TARGET */
52 #include "aout2bb.h"
53 #include "chksum.h"
55 void usage(void);
56 int intcmp(const void *, const void *);
57 int main(int argc, char *argv[]);
59 #ifdef DEBUG
60 #define dprintf(x) printf x
61 #else
62 #define dprintf(x)
63 #endif
65 #define BBSIZE 8192
67 char *progname;
68 int bbsize = BBSIZE;
69 u_int8_t *buffer;
70 u_int32_t *relbuf;
71 /* can't have more relocs than that*/
73 extern char *optarg;
75 int
76 intcmp(const void *i, const void *j)
78 int r;
80 r = (*(u_int32_t *)i) < (*(u_int32_t *)j);
82 return 2*r-1;
85 int
86 main(int argc, char *argv[])
88 int ifd, ofd;
89 u_int mid, flags, magic;
90 void *image;
91 struct exec *eh;
92 struct relocation_info_m68k *rpi;
93 u_int32_t *lptr;
94 int i, delta;
95 u_int8_t *rpo;
96 u_int32_t oldaddr, addrdiff;
97 u_int32_t tsz, dsz, bsz, trsz, drsz, entry, relver;
98 int sumsize = 16;
99 int c;
102 progname = argv[0];
104 /* insert getopt here, if needed */
105 while ((c = getopt(argc, argv, "FS:")) != -1)
106 switch(c) {
107 case 'F':
108 sumsize = 2;
109 break;
110 case 'S':
111 bbsize = (atoi(optarg) + 511) & ~511;
112 break;
113 default:
114 usage();
116 argv += optind;
117 argc -= optind;
119 if (argc < 2)
120 usage();
122 buffer = malloc(bbsize);
123 relbuf = (u_int32_t *)malloc(bbsize);
124 if (buffer == NULL || relbuf == NULL)
125 err(1, "Unable to allocate memory");
127 ifd = open(argv[0], O_RDONLY, 0);
128 if (ifd < 0)
129 err(1, "Can't open %s", argv[0]);
131 /* XXX stat(ifd, sb), mmap(0, sb.st_size); */
132 image = mmap(0, 65536, PROT_READ, MAP_FILE|MAP_PRIVATE, ifd, 0);
133 if (image == 0)
134 err(1, "Can't mmap %s", argv[1]);
136 eh = (struct exec *)image; /* XXX endianness */
138 magic = N_GETMAGIC(*eh);
139 if (magic != OMAGIC)
140 errx(1, "%s isn't an OMAGIC file, but 0%o", argv[0], magic);
142 flags = N_GETFLAG(*eh);
143 if (flags != 0)
144 errx(1, "%s has strange exec flags 0x%x", argv[0], flags);
146 mid = N_GETMID(*eh);
147 switch(mid) {
148 case MID_M68K:
149 case MID_M68K4K:
150 break;
151 default:
152 errx(1, "%s has strange machine id 0x%x (%d)", argv[0], mid,
153 mid);
156 tsz = ntohl(eh->a_text);
157 dsz = ntohl(eh->a_data);
158 bsz = ntohl(eh->a_bss);
159 trsz = ntohl(eh->a_trsize);
160 drsz = ntohl(eh->a_drsize);
161 entry = ntohl(eh->a_entry);
163 dprintf(("tsz = 0x%x, dsz = 0x%x, bsz = 0x%x, total 0x%x, entry=0x%x\n",
164 tsz, dsz, bsz, tsz+dsz+bsz, entry));
166 if ((trsz+drsz)==0)
167 errx(1, "%s has no relocation records.", argv[0]);
169 dprintf(("%d text relocs, %d data relocs\n", trsz/8, drsz/8));
170 if (entry != 12)
171 errx(1, "%s: entry point 0x%04x is not 0x000c", argv[0],
172 entry);
175 * We have one contiguous area allocated by the ROM to us.
177 if (tsz+dsz+bsz > bbsize)
178 errx(1, "%s: resulting image too big", argv[0]);
180 memset(buffer, 0, sizeof(buffer));
181 memcpy(buffer, image + N_TXTOFF(*eh), tsz+dsz);
184 * Hm. This tool REALLY should understand more than one
185 * relocator version. For now, check that the relocator at
186 * the image start does understand what we output.
188 relver = ntohl(*(u_int32_t *)(image+0x24));
189 switch (relver) {
190 default:
191 errx(1, "%s: unrecognized relocator version %d",
192 argv[0], relver);
193 /*NOTREACHED*/
195 case RELVER_RELATIVE_BYTES:
196 rpo = buffer + bbsize - 1;
197 delta = -1;
198 break;
200 case RELVER_RELATIVE_BYTES_FORWARD:
201 rpo = buffer + tsz + dsz;
202 delta = +1;
203 *(u_int16_t *)(buffer + 14) = htons(tsz + dsz);
204 break;
209 i = 0;
211 for (rpi = (struct relocation_info_m68k *)(image+N_TRELOFF(*eh));
212 (void *)rpi < image+N_TRELOFF(*eh)+trsz; rpi++) {
214 BE32TOH(((u_int32_t *)rpi)[0]);
215 BE32TOH(((u_int32_t *)rpi)[1]);
217 dprintf(("0x%08x 0x%08x %c\n", *(u_int32_t *)rpi,
218 ((u_int32_t *)rpi)[1], rpi->r_extern ? 'U' : ' '));
220 if (rpi->r_extern)
221 errx(1, "code accesses unresolved symbol");
222 if (rpi->r_copy)
223 errx(1, "code accesses r_copy symbol");
224 if (rpi->r_jmptable)
225 errx(1, "code accesses r_jmptable symbol");
226 if (rpi->r_relative)
227 errx(1, "code accesses r_relative symbol");
228 if (rpi->r_baserel)
229 errx(1, "code accesses r_baserel symbol");
232 * We don't worry about odd sized symbols which are pc
233 * relative, so test for pcrel first:
236 if (rpi->r_pcrel)
237 continue;
239 if (rpi->r_length != 2)
240 errx(1, "code accesses size %d symbol", rpi->r_length);
242 relbuf[i++] = rpi->r_address;
245 for (rpi = (struct relocation_info_m68k *)(image+N_DRELOFF(*eh));
246 (void *)rpi < image+N_DRELOFF(*eh)+drsz; rpi++) {
248 BE32TOH(((u_int32_t *)rpi)[0]);
249 BE32TOH(((u_int32_t *)rpi)[1]);
251 dprintf(("0x%08x 0x%08x %c\n", *(u_int32_t *)rpi,
252 ((u_int32_t *)rpi)[1], rpi->r_extern ? 'U' : ' '));
254 if (rpi->r_extern)
255 errx(1, "data accesses unresolved symbol");
256 if (rpi->r_copy)
257 errx(1, "data accesses r_copy symbol");
258 if (rpi->r_jmptable)
259 errx(1, "data accesses r_jmptable symbol");
260 if (rpi->r_relative)
261 errx(1, "data accesses r_relative symbol");
262 if (rpi->r_baserel)
263 errx(1, "data accesses r_baserel symbol");
266 * We don't worry about odd sized symbols which are pc
267 * relative, so test for pcrel first:
270 if (rpi->r_pcrel)
271 continue;
273 if (rpi->r_length != 2)
274 errx(1, "data accesses size %d symbol", rpi->r_length);
277 relbuf[i++] = rpi->r_address + tsz;
279 printf("%d absolute reloc%s found, ", i, i==1?"":"s");
281 if (i > 1)
282 heapsort(relbuf, i, 4, intcmp);
284 oldaddr = 0;
286 for (--i; i>=0; --i) {
287 dprintf(("0x%04x: ", relbuf[i]));
288 lptr = (u_int32_t *)&buffer[relbuf[i]];
289 addrdiff = relbuf[i] - oldaddr;
290 dprintf(("(0x%04x, 0x%04x): ", *lptr, addrdiff));
291 if (addrdiff > 255) {
292 *rpo = 0;
293 if (delta > 0) {
294 ++rpo;
295 *rpo++ = (relbuf[i] >> 8) & 0xff;
296 *rpo++ = relbuf[i] & 0xff;
297 dprintf(("%02x%02x%02x\n",
298 rpo[-3], rpo[-2], rpo[-1]));
299 } else {
300 *--rpo = relbuf[i] & 0xff;
301 *--rpo = (relbuf[i] >> 8) & 0xff;
302 --rpo;
303 dprintf(("%02x%02x%02x\n",
304 rpo[0], rpo[1], rpo[2]));
306 } else {
307 *rpo = addrdiff;
308 dprintf(("%02x\n", *rpo));
309 rpo += delta;
312 oldaddr = relbuf[i];
314 if (delta < 0 ? rpo <= buffer+tsz+dsz
315 : rpo >= buffer + bbsize)
316 errx(1, "Relocs don't fit.");
318 *rpo = 0; rpo += delta;
319 *rpo = 0; rpo += delta;
320 *rpo = 0; rpo += delta;
322 printf("using %d bytes, %d bytes remaining.\n", delta > 0 ?
323 rpo-buffer-tsz-dsz : buffer+bbsize-rpo, delta > 0 ?
324 buffer + bbsize - rpo : rpo - buffer - tsz - dsz);
326 * RELOCs must fit into the bss area.
328 if (delta < 0 ? rpo <= buffer+tsz+dsz
329 : rpo >= buffer + bbsize)
330 errx(1, "Relocs don't fit.");
332 ((u_int32_t *)buffer)[1] = 0;
333 ((u_int32_t *)buffer)[1] =
334 (0xffffffff - chksum((u_int32_t *)buffer, sumsize * 512 / 4));
336 ofd = open(argv[1], O_CREAT|O_WRONLY, 0644);
337 if (ofd < 0)
338 err(1, "Can't open %s", argv[1]);
340 if (write(ofd, buffer, bbsize) != bbsize)
341 err(1, "Writing output file");
343 exit(0);
346 void
347 usage(void)
349 fprintf(stderr, "Usage: %s [-F] [-S bbsize] bootprog bootprog.bin\n",
350 progname);
351 exit(1);
352 /* NOTREACHED */