1 /* $NetBSD: aout2bb.c,v 1.14 2008/04/28 20:23:13 martin Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
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
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"
36 #include <sys/types.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 */
56 int intcmp(const void *, const void *);
57 int main(int argc
, char *argv
[]);
60 #define dprintf(x) printf x
71 /* can't have more relocs than that*/
76 intcmp(const void *i
, const void *j
)
80 r
= (*(u_int32_t
*)i
) < (*(u_int32_t
*)j
);
86 main(int argc
, char *argv
[])
89 u_int mid
, flags
, magic
;
92 struct relocation_info_m68k
*rpi
;
96 u_int32_t oldaddr
, addrdiff
;
97 u_int32_t tsz
, dsz
, bsz
, trsz
, drsz
, entry
, relver
;
104 /* insert getopt here, if needed */
105 while ((c
= getopt(argc
, argv
, "FS:")) != -1)
111 bbsize
= (atoi(optarg
) + 511) & ~511;
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);
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);
134 err(1, "Can't mmap %s", argv
[1]);
136 eh
= (struct exec
*)image
; /* XXX endianness */
138 magic
= N_GETMAGIC(*eh
);
140 errx(1, "%s isn't an OMAGIC file, but 0%o", argv
[0], magic
);
142 flags
= N_GETFLAG(*eh
);
144 errx(1, "%s has strange exec flags 0x%x", argv
[0], flags
);
152 errx(1, "%s has strange machine id 0x%x (%d)", argv
[0], 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
));
167 errx(1, "%s has no relocation records.", argv
[0]);
169 dprintf(("%d text relocs, %d data relocs\n", trsz
/8, drsz
/8));
171 errx(1, "%s: entry point 0x%04x is not 0x000c", argv
[0],
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));
191 errx(1, "%s: unrecognized relocator version %d",
195 case RELVER_RELATIVE_BYTES
:
196 rpo
= buffer
+ bbsize
- 1;
200 case RELVER_RELATIVE_BYTES_FORWARD
:
201 rpo
= buffer
+ tsz
+ dsz
;
203 *(u_int16_t
*)(buffer
+ 14) = htons(tsz
+ dsz
);
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' : ' '));
221 errx(1, "code accesses unresolved symbol");
223 errx(1, "code accesses r_copy symbol");
225 errx(1, "code accesses r_jmptable symbol");
227 errx(1, "code accesses r_relative symbol");
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:
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' : ' '));
255 errx(1, "data accesses unresolved symbol");
257 errx(1, "data accesses r_copy symbol");
259 errx(1, "data accesses r_jmptable symbol");
261 errx(1, "data accesses r_relative symbol");
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:
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");
282 heapsort(relbuf
, i
, 4, intcmp
);
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) {
295 *rpo
++ = (relbuf
[i
] >> 8) & 0xff;
296 *rpo
++ = relbuf
[i
] & 0xff;
297 dprintf(("%02x%02x%02x\n",
298 rpo
[-3], rpo
[-2], rpo
[-1]));
300 *--rpo
= relbuf
[i
] & 0xff;
301 *--rpo
= (relbuf
[i
] >> 8) & 0xff;
303 dprintf(("%02x%02x%02x\n",
304 rpo
[0], rpo
[1], rpo
[2]));
308 dprintf(("%02x\n", *rpo
));
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);
338 err(1, "Can't open %s", argv
[1]);
340 if (write(ofd
, buffer
, bbsize
) != bbsize
)
341 err(1, "Writing output file");
349 fprintf(stderr
, "Usage: %s [-F] [-S bbsize] bootprog bootprog.bin\n",