/[gxemul]/trunk/src/file.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14 - (show annotations)
Mon Oct 8 16:18:51 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 56559 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.982 2005/10/07 22:45:32 debug Exp $
20050816	Some success in decoding the way the SGI O2 PROM draws graphics
		during bootup; lines/rectangles and bitmaps work, enough to
		show the bootlogo etc. :-)
		Adding more PPC instructions, and (dummy) BAT registers.
20050817	Updating the pckbc to support scancode type 3 keyboards
		(required in order to interact with the SGI O2 PROM).
		Adding more PPC instructions.
20050818	Adding more ARM instructions; general register forms.
		Importing armreg.h from NetBSD (ARM cpu ids). Adding a (dummy)
		CATS machine mode (using SA110 as the default CPU).
		Continuing on general dyntrans related stuff.
20050819	Register forms for ARM load/stores. Gaah! The Compaq C Compiler
		bug is triggered for ARM loads as well, not just PPC :-(
		Adding full support for ARM PC-relative load/stores, and load/
		stores where the PC register is the destination register.
		Adding support for ARM a.out binaries.
20050820	Continuing to add more ARM instructions, and correcting some
		bugs. Continuing on CATS emulation.
		More work on the PPC stuff.
20050821	Minor PPC and ARM updates. Adding more machine types.
20050822	All ARM "data processing instructions" are now generated
		automatically.
20050824	Beginning the work on the ARM system control coprocessor.
		Adding support for ARM halfword load/stores, and signed loads.
20050825	Fixing an important bug related to the ARM condition codes.
		OpenBSD/zaurus and NetBSD/netwinder now print some boot
		messages. :)
		Adding a dummy SH (Hitachi SuperH) cpu family.
		Beginning to add some ARM virtual address translation.
		MIPS bugfixes: unaligned PC now cause an ADEL exception (at
		least for non-bintrans execution), and ADEL/ADES (not
		TLBL/TLBS) are used if userland tries to access kernel space.
		(Thanks to Joshua Wise for making me aware of these bugs.)
20050827	More work on the ARM emulation, and various other updates.
20050828	More ARM updates.
		Finally taking the time to work on translation invalidation
		(i.e. invalidating translated code mappings when memory is
		written to). Hopefully this doesn't break anything.
20050829	Moving CPU related files from src/ to a new subdir, src/cpus/.
		Moving PROM emulation stuff from src/ to src/promemul/.
		Better debug instruction trace for ARM loads and stores.
20050830	Various ARM updates (correcting CMP flag calculation, etc).
20050831	PPC instruction updates. (Flag fixes, etc.)
20050901	Various minor PPC and ARM instruction emulation updates.
		Minor OpenFirmware emulation updates.
20050903	Adding support for adding arbitrary ARM coprocessors (with
		the i80321 I/O coprocessor as a first test).
		Various other ARM and PPC updates.
20050904	Adding some SHcompact disassembly routines.
20050907	(Re)adding a dummy HPPA CPU module, and a dummy i960 module.
20050908	Began hacking on some Apple Partition Table support.
20050909	Adding support for loading Mach-O (Darwin PPC) binaries.
20050910	Fixing an ARM bug (Carry flag was incorrectly updated for some
		data processing instructions); OpenBSD/cats and NetBSD/
		netwinder get quite a bit further now.
		Applying a patch to dev_wdc, and a one-liner to dev_pcic, to
		make them work better when emulating new versions of OpenBSD.
		(Thanks to Alexander Yurchenko for the patches.)
		Also doing some other minor updates to dev_wdc. (Some cleanup,
		and finally converting to devinit, etc.)
20050912	IRIX doesn't have u_int64_t by default (noticed by Andreas
		<avr@gnulinux.nl>); configure updated to reflect this.
		Working on ARM register bank switching, CPSR vs SPSR issues,
		and beginning the work on interrupt/exception support.
20050913	Various minor ARM updates (speeding up load/store multiple,
		and fixing a ROR bug in R(); NetBSD/cats now boots as far as
		OpenBSD/cats).
20050917	Adding a dummy Atmel AVR (8-bit) cpu family skeleton.
20050918	Various minor updates.
20050919	Symbols are now loaded from Mach-O executables.
		Continuing the work on adding ARM exception support.
20050920	More work on ARM stuff: OpenBSD/cats and NetBSD/cats reach
		userland! :-)
20050921	Some more progress on ARM interrupt specifics.
20050923	Fixing linesize for VR4121 (patch by Yurchenko). Also fixing
		linesizes/cachesizes for some other VR4xxx.
		Adding a dummy Acer Labs M1543 PCI-ISA bridge (for CATS) and a
		dummy Symphony Labs 83C553 bridge (for Netwinder), usable by 
		dev_footbridge.
20050924	Some PPC progress.
20050925	More PPC progress.
20050926	PPC progress (fixing some bugs etc); Darwin's kernel gets
		slightly further than before.
20050928	Various updates: footbridge/ISA/pciide stuff, and finally
		fixing the VGA text scroll-by-changing-the-base-offset bug.
20050930	Adding a dummy S3 ViRGE pci card for CATS emulation, which
		both NetBSD and OpenBSD detects as VGA.
		Continuing on Footbridge (timers, ISA interrupt stuff).
20051001	Continuing... there are still bugs, probably interrupt-
		related.
20051002	More work on the Footbridge (interrupt stuff).
20051003	Various minor updates. (Trying to find the bug(s).)
20051004	Continuing on the ARM stuff.
20051005	More ARM-related fixes.
20051007	FINALLY! Found and fixed 2 ARM bugs: 1 memory related, and the
		other was because of an error in the ARM manual (load multiple
		with the S-bit set should _NOT_ load usermode registers, as the
		manual says, but it should load saved registers, which may or
		may not happen to be usermode registers).
		NetBSD/cats and OpenBSD/cats seem to install fine now :-)
		except for a minor bug at the end of the OpenBSD/cats install.
		Updating the documentation, preparing for the next release.
20051008	Continuing with release testing and cleanup.

1 /*
2 * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: file.c,v 1.116 2005/09/30 14:07:45 debug Exp $
29 *
30 * This file contains functions which load executable images into (emulated)
31 * memory. File formats recognized so far are:
32 *
33 * a.out old format used by OpenBSD 2.x pmax kernels
34 * Mach-O MacOS X format, etc.
35 * ecoff old format used by Ultrix, Windows NT, etc
36 * srec Motorola SREC format
37 * raw raw binaries, "address:[skiplen:[entrypoint:]]filename"
38 * ELF 32-bit and 64-bit ELFs
39 *
40 * If a file is not of one of the above mentioned formats, it is assumed
41 * to be symbol data generated by 'nm' or 'nm -S'.
42 */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/types.h>
48
49 #include "cpu.h"
50 #include "exec_aout.h"
51 #include "exec_ecoff.h"
52 #include "exec_elf.h"
53 #include "machine.h"
54 #include "memory.h"
55 #include "misc.h"
56 #include "symbol.h"
57
58
59 /* ELF machine types as strings: (same as exec_elf.h) */
60 #define N_ELF_MACHINE_TYPES 64
61 static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
62 "NONE", "M32", "SPARC", "386", /* 0..3 */
63 "68K", "88K", "486", "860", /* 4..7 */
64 "MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */
65 "unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */
66 "NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */
67 "PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */
68 "unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */
69 "unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */
70 "unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */
71 "V800", "FR20", "RH32", "RCE", /* 36..39 */
72 "ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */
73 "TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */
74 "H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */
75 "COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */
76 "unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */
77 "unknown60", "unknown61", "AMD64", "unknown63" /* 60..63 */
78 };
79
80
81 /*
82 * This should be increased by every routine here that actually loads an
83 * executable file into memory. (For example, loading a symbol file should
84 * NOT increase this.)
85 */
86 static int n_executables_loaded = 0;
87
88
89 struct aout_symbol {
90 uint32_t strindex;
91 uint32_t type;
92 uint32_t addr;
93 };
94
95 /* Special symbol format used by Microsoft-ish COFF files: */
96 struct ms_sym {
97 unsigned char name[8];
98 unsigned char value[4];
99 unsigned char section[2];
100 unsigned char type[2];
101 unsigned char storage_class;
102 unsigned char n_aux_syms;
103 };
104
105
106 #define unencode(var,dataptr,typ) { \
107 int Wi; unsigned char Wb; \
108 unsigned char *Wp = (unsigned char *) dataptr; \
109 int Wlen = sizeof(typ); \
110 var = 0; \
111 for (Wi=0; Wi<Wlen; Wi++) { \
112 if (encoding == ELFDATA2LSB) \
113 Wb = Wp[Wlen-1 - Wi]; \
114 else \
115 Wb = Wp[Wi]; \
116 if (Wi == 0 && (Wb & 0x80)) { \
117 var --; /* set var to -1 :-) */ \
118 var <<= 8; \
119 } \
120 var |= Wb; \
121 if (Wi < Wlen-1) \
122 var <<= 8; \
123 } \
124 }
125
126
127 #define AOUT_FLAG_DECOSF1 1
128 #define AOUT_FLAG_FROM_BEGINNING 2
129 #define AOUT_FLAG_VADDR_ZERO_HACK 4
130 /*
131 * file_load_aout():
132 *
133 * Loads an a.out binary image into the emulated memory. The entry point
134 * (read from the a.out header) is stored in the specified CPU's registers.
135 *
136 * TODO: This has to be rewritten / corrected to support multiple a.out
137 * formats, where text/data are aligned differently.
138 */
139 static void file_load_aout(struct machine *m, struct memory *mem,
140 char *filename, int flags,
141 uint64_t *entrypointp, int arch, int *byte_orderp)
142 {
143 struct exec aout_header;
144 FILE *f;
145 int len;
146 int encoding = ELFDATA2LSB;
147 uint32_t entry, datasize, textsize;
148 int32_t symbsize = 0;
149 uint32_t vaddr, total_len;
150 unsigned char buf[65536];
151 unsigned char *syms;
152
153 if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
154 encoding = ELFDATA2MSB;
155
156 f = fopen(filename, "r");
157 if (f == NULL) {
158 perror(filename);
159 exit(1);
160 }
161
162 if (flags & AOUT_FLAG_DECOSF1) {
163 fread(&buf, 1, 32, f);
164 vaddr = buf[16] + (buf[17] << 8) +
165 (buf[18] << 16) + (buf[19] << 24);
166 entry = buf[20] + (buf[21] << 8) +
167 (buf[22] << 16) + (buf[23] << 24);
168 debug("OSF1 a.out, load address 0x%08lx, "
169 "entry point 0x%08x\n", (long)vaddr, (long)entry);
170 symbsize = 0;
171 fseek(f, 0, SEEK_END);
172 /* This is of course wrong, but should work anyway: */
173 textsize = ftello(f) - 512;
174 datasize = 0;
175 fseek(f, 512, SEEK_SET);
176 } else {
177 len = fread(&aout_header, 1, sizeof(aout_header), f);
178 if (len != sizeof(aout_header)) {
179 fprintf(stderr, "%s: not a complete a.out image\n",
180 filename);
181 exit(1);
182 }
183
184 unencode(entry, &aout_header.a_entry, uint32_t);
185 debug("a.out, entry point 0x%08lx\n", (long)entry);
186 vaddr = entry;
187
188 if (flags & AOUT_FLAG_VADDR_ZERO_HACK)
189 vaddr = 0;
190
191 unencode(textsize, &aout_header.a_text, uint32_t);
192 unencode(datasize, &aout_header.a_data, uint32_t);
193 debug("text + data = %i + %i bytes\n", textsize, datasize);
194
195 unencode(symbsize, &aout_header.a_syms, uint32_t);
196 }
197
198 if (flags & AOUT_FLAG_FROM_BEGINNING) {
199 fseek(f, 0, SEEK_SET);
200 vaddr &= ~0xfff;
201 }
202
203 /* Load text and data: */
204 total_len = textsize + datasize;
205 while (total_len != 0) {
206 len = total_len > sizeof(buf) ? sizeof(buf) : total_len;
207 len = fread(buf, 1, len, f);
208
209 /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
210 (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
211
212 if (len > 0) {
213 int len2 = 0;
214 uint64_t vaddr1 = vaddr &
215 ((1 << BITS_PER_MEMBLOCK) - 1);
216 uint64_t vaddr2 = (vaddr +
217 len) & ((1 << BITS_PER_MEMBLOCK) - 1);
218 if (vaddr2 < vaddr1) {
219 len2 = len - vaddr2;
220 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
221 &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
222 }
223 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
224 &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
225 } else {
226 if (flags & AOUT_FLAG_DECOSF1)
227 break;
228 else {
229 fprintf(stderr, "could not read from %s\n",
230 filename);
231 exit(1);
232 }
233 }
234
235 vaddr += len;
236 total_len -= len;
237 }
238
239 if (symbsize != 0) {
240 struct aout_symbol *aout_symbol_ptr;
241 int i, n_symbols;
242 uint32_t type, addr, str_index;
243 uint32_t strings_len;
244 char *string_symbols;
245 off_t oldpos;
246
247 debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
248 syms = malloc(symbsize);
249 if (syms == NULL) {
250 fprintf(stderr, "out of memory\n");
251 exit(1);
252 }
253 len = fread(syms, 1, symbsize, f);
254 if (len != symbsize) {
255 fprintf(stderr, "error reading symbols from %s\n",
256 filename);
257 exit(1);
258 }
259
260 oldpos = ftello(f);
261 fseek(f, 0, SEEK_END);
262 strings_len = ftello(f) - oldpos;
263 fseek(f, oldpos, SEEK_SET);
264 debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
265 string_symbols = malloc(strings_len);
266 if (string_symbols == NULL) {
267 fprintf(stderr, "out of memory\n");
268 exit(1);
269 }
270 fread(string_symbols, 1, strings_len, f);
271
272 aout_symbol_ptr = (struct aout_symbol *) syms;
273 n_symbols = symbsize / sizeof(struct aout_symbol);
274 i = 0;
275 while (i < n_symbols) {
276 unencode(str_index, &aout_symbol_ptr[i].strindex,
277 uint32_t);
278 unencode(type, &aout_symbol_ptr[i].type, uint32_t);
279 unencode(addr, &aout_symbol_ptr[i].addr, uint32_t);
280
281 /* debug("symbol type 0x%04x @ 0x%08x: %s\n",
282 type, addr, string_symbols + str_index); */
283
284 if (type != 0 && addr != 0)
285 add_symbol_name(&m->symbol_context,
286 addr, 0, string_symbols + str_index, 0, -1);
287 i++;
288 }
289
290 free(string_symbols);
291 free(syms);
292 }
293
294 fclose(f);
295
296 *entrypointp = (int32_t)entry;
297
298 if (encoding == ELFDATA2LSB)
299 *byte_orderp = EMUL_LITTLE_ENDIAN;
300 else
301 *byte_orderp = EMUL_BIG_ENDIAN;
302
303 n_executables_loaded ++;
304 }
305
306
307 /*
308 * file_load_macho():
309 *
310 * Loads a Mach-O binary image into the emulated memory. The entry point
311 * is stored in the specified CPU's registers.
312 *
313 * TODO:
314 *
315 * o) Almost everything.
316 *
317 * o) I haven't had time to look into whether Apple's open source
318 * license is BSD-compatible or not. Perhaps it would be possible
319 * to use a header file containing symbolic names, and not use
320 * hardcoded values.
321 */
322 static void file_load_macho(struct machine *m, struct memory *mem,
323 char *filename, uint64_t *entrypointp, int arch, int *byte_orderp,
324 int is_64bit, int is_reversed)
325 {
326 FILE *f;
327 uint64_t entry = 0;
328 int entry_set = 0;
329 int encoding = ELFDATA2MSB;
330 unsigned char buf[65536];
331 char *symbols, *strings;
332 uint32_t cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
333 uint64_t vmaddr, vmsize, fileoff, filesize;
334 int cmd_type, cmd_len, pos, i, flavor;
335 int32_t symoff, nsyms, stroff, strsize;
336 size_t len;
337
338 if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
339 encoding = ELFDATA2MSB;
340
341 f = fopen(filename, "r");
342 if (f == NULL) {
343 perror(filename);
344 exit(1);
345 }
346
347 if (is_64bit) {
348 fatal("TODO: 64-bit Mach-O. Not supported yet.\n");
349 exit(1);
350 }
351 if (is_reversed) {
352 fatal("TODO: Reversed-endianness. Not supported yet.\n");
353 exit(1);
354 }
355
356 len = fread(buf, 1, sizeof(buf), f);
357 if (len < 100) {
358 fatal("Bad Mach-O file?\n");
359 exit(1);
360 }
361
362 unencode(cputype, &buf[4], uint32_t);
363 unencode(cpusubtype, &buf[8], uint32_t);
364 unencode(filetype, &buf[12], uint32_t);
365 unencode(ncmds, &buf[16], uint32_t);
366 unencode(sizeofcmds, &buf[20], uint32_t);
367 unencode(flags, &buf[24], uint32_t);
368
369 /* debug("cputype=0x%x cpusubtype=0x%x filetype=0x%x\n",
370 cputype, cpusubtype, filetype);
371 debug("ncmds=%i sizeofcmds=0x%08x flags=0x%08x\n",
372 ncmds, sizeofcmds, flags); */
373
374 /*
375 * Compare to "normal" values.
376 * NOTE/TODO: These were for a Darwin (Macintosh PPC) kernel.
377 */
378 if (cputype != 0x12) {
379 fatal("Error: Unimplemented cputype 0x%x\n", cputype);
380 exit(1);
381 }
382 if (cpusubtype != 0) {
383 fatal("Error: Unimplemented cpusubtype 0x%x\n", cpusubtype);
384 exit(1);
385 }
386 /* Filetype 2 means an executable image. */
387 if (filetype != 2) {
388 fatal("Error: Unimplemented filetype 0x%x\n", filetype);
389 exit(1);
390 }
391 if (!(flags & 1)) {
392 fatal("Error: File has 'undefined references'. Cannot"
393 " be executed.\n", flags);
394 exit(1);
395 }
396
397 /* I've only encountered flags == 1 so far. */
398 if (flags != 1) {
399 fatal("Error: Unimplemented flags 0x%x\n", flags);
400 exit(1);
401 }
402
403 /*
404 * Read all load commands:
405 */
406 pos = is_64bit? 32 : 28;
407 cmd_type = 0;
408 do {
409 /* Read command type and length: */
410 unencode(cmd_type, &buf[pos], uint32_t);
411 unencode(cmd_len, &buf[pos+4], uint32_t);
412
413 #if 0
414 debug("cmd %i, len=%i\n", cmd_type, cmd_len);
415 for (i=8; i<cmd_len; i++) {
416 unsigned char ch = buf[pos+i];
417 if (ch >= ' ' && ch < 127)
418 debug("%c", ch);
419 else
420 debug(".");
421 }
422 #endif
423 switch (cmd_type) {
424 case 1: /* LC_SEGMENT */
425 debug("seg ");
426 for (i=0; i<16; i++) {
427 if (buf[pos + 8 + i] == 0)
428 break;
429 debug("%c", buf[pos + 8 + i]);
430 }
431 unencode(vmaddr, &buf[pos+8+16+0], uint32_t);
432 unencode(vmsize, &buf[pos+8+16+4], uint32_t);
433 unencode(fileoff, &buf[pos+8+16+8], uint32_t);
434 unencode(filesize, &buf[pos+8+16+12], uint32_t);
435 debug(": vmaddr=0x%x size=0x%x fileoff=0x%x",
436 (int)vmaddr, (int)vmsize, (int)fileoff);
437
438 if (filesize == 0) {
439 debug("\n");
440 break;
441 }
442
443 fseek(f, fileoff, SEEK_SET);
444
445 /* Load data from the file: */
446 while (filesize != 0) {
447 unsigned char buf[32768];
448 ssize_t len = filesize > sizeof(buf) ?
449 sizeof(buf) : filesize;
450 len = fread(buf, 1, len, f);
451
452 /* printf("fread len=%i vmaddr=%x buf[0..]="
453 "%02x %02x %02x\n", (int)len, (int)vmaddr,
454 buf[0], buf[1], buf[2]); */
455
456 if (len > 0) {
457 int len2 = 0;
458 uint64_t vaddr1 = vmaddr &
459 ((1 << BITS_PER_MEMBLOCK) - 1);
460 uint64_t vaddr2 = (vmaddr +
461 len) & ((1 << BITS_PER_MEMBLOCK)-1);
462 if (vaddr2 < vaddr1) {
463 len2 = len - vaddr2;
464 m->cpus[0]->memory_rw(m->cpus[
465 0], mem, vmaddr, &buf[0],
466 len2, MEM_WRITE,
467 NO_EXCEPTIONS);
468 }
469 m->cpus[0]->memory_rw(m->cpus[0], mem,
470 vmaddr + len2, &buf[len2], len-len2,
471 MEM_WRITE, NO_EXCEPTIONS);
472 } else {
473 fprintf(stderr, "error reading\n");
474 exit(1);
475 }
476
477 vmaddr += len;
478 filesize -= len;
479 }
480
481 debug("\n");
482 break;
483
484 case 2: /* LC_SYMTAB */
485 unencode(symoff, &buf[pos+8], uint32_t);
486 unencode(nsyms, &buf[pos+12], uint32_t);
487 unencode(stroff, &buf[pos+16], uint32_t);
488 unencode(strsize, &buf[pos+20], uint32_t);
489 debug("symtable: %i symbols @ 0x%x (strings at "
490 "0x%x)\n", nsyms, symoff, stroff);
491
492 symbols = malloc(12 * nsyms);
493 if (symbols == NULL) {
494 fprintf(stderr, "out of memory\n");
495 exit(1);
496 }
497 fseek(f, symoff, SEEK_SET);
498 fread(symbols, 1, 12 * nsyms, f);
499
500 strings = malloc(strsize);
501 if (strings == NULL) {
502 fprintf(stderr, "out of memory\n");
503 exit(1);
504 }
505 fseek(f, stroff, SEEK_SET);
506 fread(strings, 1, strsize, f);
507
508 for (i=0; i<nsyms; i++) {
509 int n_strx, n_type, n_sect, n_desc;
510 uint32_t n_value;
511 unencode(n_strx, &symbols[i*12+0], int32_t);
512 unencode(n_type, &symbols[i*12+4], uint8_t);
513 unencode(n_sect, &symbols[i*12+5], uint8_t);
514 unencode(n_desc, &symbols[i*12+6], int16_t);
515 unencode(n_value, &symbols[i*12+8], uint32_t);
516 /* debug("%i: strx=%i type=%i sect=%i desc=%i"
517 " value=0x%x\n", i, n_strx, n_type,
518 n_sect, n_desc, n_value); */
519 add_symbol_name(&m->symbol_context,
520 n_value, 0, strings + n_strx, 0, -1);
521 }
522
523 free(symbols);
524 free(strings);
525 break;
526
527 case 5: debug("unix thread context: ");
528 /* See http://cvs.sf.net/viewcvs.py/hte/
529 HT%20Editor/machostruc.h or similar for details
530 on the thread struct. */
531 unencode(flavor, &buf[pos+8], uint32_t);
532 if (flavor != 1) {
533 fatal("unimplemented flavor %i\n", flavor);
534 exit(1);
535 }
536
537 if (arch != ARCH_PPC) {
538 fatal("non-PPC arch? TODO\n");
539 exit(1);
540 }
541
542 unencode(entry, &buf[pos+16], uint32_t);
543 entry_set = 1;
544 debug("pc=0x%x\n", (int)entry);
545
546 for (i=1; i<40; i++) {
547 uint32_t x;
548 unencode(x, &buf[pos+16+i*4], uint32_t);
549 if (x != 0) {
550 fatal("Entry nr %i in the Mach-O"
551 " thread struct is non-zero"
552 " (0x%x). This is not supported"
553 " yet. TODO\n", i, x);
554 exit(1);
555 }
556 }
557 break;
558
559 default:fatal("WARNING! Unimplemented load command %i!\n",
560 cmd_type);
561 }
562
563 pos += cmd_len;
564 } while (pos < sizeofcmds && cmd_type != 0);
565
566 fclose(f);
567
568 if (!entry_set) {
569 fatal("No entry point? Aborting.\n");
570 exit(1);
571 }
572
573 *entrypointp = entry;
574
575 if (encoding == ELFDATA2LSB)
576 *byte_orderp = EMUL_LITTLE_ENDIAN;
577 else
578 *byte_orderp = EMUL_BIG_ENDIAN;
579
580 n_executables_loaded ++;
581 }
582
583
584 /*
585 * file_load_ecoff():
586 *
587 * Loads an ecoff binary image into the emulated memory. The entry point
588 * (read from the ecoff header) is stored in the specified CPU's registers.
589 */
590 static void file_load_ecoff(struct machine *m, struct memory *mem,
591 char *filename, uint64_t *entrypointp,
592 int arch, uint64_t *gpp, int *byte_orderp)
593 {
594 struct ecoff_exechdr exechdr;
595 int f_magic, f_nscns, f_nsyms;
596 int a_magic;
597 off_t f_symptr, a_tsize, a_dsize, a_bsize;
598 uint64_t a_entry, a_tstart, a_dstart, a_bstart, a_gp, end_addr=0;
599 char *format_name;
600 struct ecoff_scnhdr scnhdr;
601 FILE *f;
602 int len, secn, total_len, chunk_size;
603 int encoding = ELFDATA2LSB; /* Assume little-endian. See below */
604 int program_byte_order = -1;
605 unsigned char buf[8192];
606
607 f = fopen(filename, "r");
608 if (f == NULL) {
609 perror(filename);
610 exit(1);
611 }
612
613 len = fread(&exechdr, 1, sizeof(exechdr), f);
614 if (len != sizeof(exechdr)) {
615 fprintf(stderr, " not a complete ecoff image\n");
616 exit(1);
617 }
618
619 /*
620 * The following code looks a bit ugly, but it should work. The ECOFF
621 * 16-bit magic value seems to be stored in MSB byte order for
622 * big-endian binaries, and LSB byte order for little-endian binaries.
623 *
624 * The unencode() assumes little-endianness by default.
625 */
626 unencode(f_magic, &exechdr.f.f_magic, uint16_t);
627 switch (f_magic) {
628 case ((ECOFF_MAGIC_MIPSEB & 0xff) << 8) +
629 ((ECOFF_MAGIC_MIPSEB >> 8) & 0xff):
630 format_name = "MIPS1 BE";
631 encoding = ELFDATA2MSB;
632 break;
633 case ECOFF_MAGIC_MIPSEB:
634 /* NOTE: Big-endian header, little-endian code! */
635 format_name = "MIPS1 BE-LE";
636 encoding = ELFDATA2MSB;
637 program_byte_order = ELFDATA2LSB;
638 break;
639 case ECOFF_MAGIC_MIPSEL:
640 format_name = "MIPS1 LE";
641 encoding = ELFDATA2LSB;
642 break;
643 case ((ECOFF_MAGIC_MIPSEB2 & 0xff) << 8) +
644 ((ECOFF_MAGIC_MIPSEB2 >> 8) & 0xff):
645 format_name = "MIPS2 BE";
646 encoding = ELFDATA2MSB;
647 break;
648 case ECOFF_MAGIC_MIPSEL2:
649 format_name = "MIPS2 LE";
650 encoding = ELFDATA2LSB;
651 break;
652 case ((ECOFF_MAGIC_MIPSEB3 & 0xff) << 8) +
653 ((ECOFF_MAGIC_MIPSEB3 >> 8) & 0xff):
654 format_name = "MIPS3 BE";
655 encoding = ELFDATA2MSB;
656 break;
657 case ECOFF_MAGIC_MIPSEL3:
658 format_name = "MIPS3 LE";
659 encoding = ELFDATA2LSB;
660 break;
661 default:
662 fprintf(stderr, "%s: unimplemented ECOFF format, magic = "
663 "0x%04x\n", filename, (int)f_magic);
664 exit(1);
665 }
666
667 /* Read various header information: */
668 unencode(f_nscns, &exechdr.f.f_nscns, uint16_t);
669 unencode(f_symptr, &exechdr.f.f_symptr, uint32_t);
670 unencode(f_nsyms, &exechdr.f.f_nsyms, uint32_t);
671 debug("ECOFF, %s, %i sections, %i symbols @ 0x%lx\n",
672 format_name, f_nscns, f_nsyms, (long)f_symptr);
673
674 unencode(a_magic, &exechdr.a.magic, uint16_t);
675 unencode(a_tsize, &exechdr.a.tsize, uint32_t);
676 unencode(a_dsize, &exechdr.a.dsize, uint32_t);
677 unencode(a_bsize, &exechdr.a.bsize, uint32_t);
678 debug("magic 0x%04x, tsize 0x%x, dsize 0x%x, bsize 0x%x\n",
679 a_magic, (int)a_tsize, (int)a_dsize, (int)a_bsize);
680
681 unencode(a_tstart, &exechdr.a.text_start, uint32_t);
682 unencode(a_dstart, &exechdr.a.data_start, uint32_t);
683 unencode(a_bstart, &exechdr.a.bss_start, uint32_t);
684 debug("text @ 0x%08x, data @ 0x%08x, bss @ 0x%08x\n",
685 (int)a_tstart, (int)a_dstart, (int)a_bstart);
686
687 unencode(a_entry, &exechdr.a.entry, uint32_t);
688 unencode(a_gp, &exechdr.a.gp_value, uint32_t);
689 debug("entrypoint 0x%08x, gp = 0x%08x\n",
690 (int)a_entry, (int)a_gp);
691
692 /*
693 * Special hack for a MACH/pmax kernel, I don't know how applicable
694 * this is for other files:
695 * there are no sections (!), and a_magic = 0x0108 instead of
696 * 0x0107 as it is on most other (E)COFF files I've seen.
697 *
698 * Then load everything after the header to the text start address.
699 */
700 if (f_nscns == 0 && a_magic == 0x108) {
701 uint64_t where = a_tstart;
702 total_len = 0;
703 fseek(f, 0x50, SEEK_SET);
704 while (!feof(f)) {
705 chunk_size = 256;
706 len = fread(buf, 1, chunk_size, f);
707
708 if (len > 0)
709 m->cpus[0]->memory_rw(m->cpus[0], mem, where,
710 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
711 where += len;
712 total_len += len;
713 }
714 debug("MACH/pmax hack (!), read 0x%x bytes\n", total_len);
715 }
716
717 /* Go through all the section headers: */
718 for (secn=0; secn<f_nscns; secn++) {
719 off_t s_scnptr, s_relptr, s_lnnoptr, oldpos;
720 int s_nreloc, s_nlnno, s_flags;
721 int s_size;
722 unsigned int i;
723 uint64_t s_paddr, s_vaddr;
724
725 /* Read a section header: */
726 len = fread(&scnhdr, 1, sizeof(scnhdr), f);
727 if (len != sizeof(scnhdr)) {
728 fprintf(stderr, "%s: incomplete section "
729 "header %i\n", filename, secn);
730 exit(1);
731 }
732
733 /* Show the section name: */
734 debug("section ");
735 for (i=0; i<sizeof(scnhdr.s_name); i++)
736 if (scnhdr.s_name[i] >= 32 && scnhdr.s_name[i] < 127)
737 debug("%c", scnhdr.s_name[i]);
738 else
739 break;
740 debug(" (");
741
742 unencode(s_paddr, &scnhdr.s_paddr, uint32_t);
743 unencode(s_vaddr, &scnhdr.s_vaddr, uint32_t);
744 unencode(s_size, &scnhdr.s_size, uint32_t);
745 unencode(s_scnptr, &scnhdr.s_scnptr, uint32_t);
746 unencode(s_relptr, &scnhdr.s_relptr, uint32_t);
747 unencode(s_lnnoptr, &scnhdr.s_lnnoptr, uint32_t);
748 unencode(s_nreloc, &scnhdr.s_nreloc, uint16_t);
749 unencode(s_nlnno, &scnhdr.s_nlnno, uint16_t);
750 unencode(s_flags, &scnhdr.s_flags, uint32_t);
751
752 debug("0x%x @ 0x%08x, offset 0x%lx, flags 0x%x)\n",
753 (int)s_size, (int)s_vaddr, (long)s_scnptr, (int)s_flags);
754
755 end_addr = s_vaddr + s_size;
756
757 if (s_relptr != 0) {
758 /*
759 * TODO: Read this url, or similar:
760 * http://www.iecc.com/linker/linker07.html
761 */
762 fprintf(stderr, "%s: relocatable code/data in "
763 "section nr %i: not yet implemented\n",
764 filename, secn);
765 exit(1);
766 }
767
768 /* Loadable? Then load the section: */
769 if (s_scnptr != 0 && s_size != 0 &&
770 s_vaddr != 0 && !(s_flags & 0x02)) {
771 /* Remember the current file offset: */
772 oldpos = ftello(f);
773
774 /* Load the section into emulated memory: */
775 fseek(f, s_scnptr, SEEK_SET);
776 total_len = 0;
777 chunk_size = 1;
778 if ((s_vaddr & 0xf) == 0) chunk_size = 0x10;
779 if ((s_vaddr & 0xff) == 0) chunk_size = 0x100;
780 if ((s_vaddr & 0xfff) == 0) chunk_size = 0x1000;
781 while (total_len < s_size) {
782 len = chunk_size;
783 if (total_len + len > s_size)
784 len = s_size - total_len;
785 len = fread(buf, 1, chunk_size, f);
786 if (len == 0) {
787 debug("!!! total_len = %i, "
788 "chunk_size = %i, len = %i\n",
789 total_len, chunk_size, len);
790 break;
791 }
792
793 m->cpus[0]->memory_rw(m->cpus[0], mem, s_vaddr,
794 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
795 s_vaddr += len;
796 total_len += len;
797 }
798
799 /* Return to position inside the section headers: */
800 fseek(f, oldpos, SEEK_SET);
801 }
802 }
803
804 if (f_symptr != 0 && f_nsyms != 0) {
805 struct ecoff_symhdr symhdr;
806 int sym_magic, iextMax, issExtMax, issMax, crfd;
807 off_t cbRfdOffset, cbExtOffset, cbSsExtOffset, cbSsOffset;
808 char *symbol_data;
809 struct ecoff_extsym *extsyms;
810 int nsymbols, sym_nr;
811
812 fseek(f, f_symptr, SEEK_SET);
813
814 len = fread(&symhdr, 1, sizeof(symhdr), f);
815 if (len != sizeof(symhdr)) {
816 fprintf(stderr, "%s: not a complete "
817 "ecoff image: symhdr broken\n", filename);
818 exit(1);
819 }
820
821 unencode(sym_magic, &symhdr.magic, uint16_t);
822 unencode(crfd, &symhdr.crfd, uint32_t);
823 unencode(cbRfdOffset, &symhdr.cbRfdOffset, uint32_t);
824 unencode(issMax, &symhdr.issMax, uint32_t);
825 unencode(cbSsOffset, &symhdr.cbSsOffset, uint32_t);
826 unencode(issExtMax, &symhdr.issExtMax, uint32_t);
827 unencode(cbSsExtOffset, &symhdr.cbSsExtOffset, uint32_t);
828 unencode(iextMax, &symhdr.iextMax, uint32_t);
829 unencode(cbExtOffset, &symhdr.cbExtOffset, uint32_t);
830
831 if (sym_magic != MIPS_MAGIC_SYM) {
832 unsigned char *ms_sym_buf;
833 struct ms_sym *sym;
834 int n_real_symbols = 0;
835
836 debug("bad symbol magic, assuming Microsoft format: ");
837
838 /*
839 * See http://www.lisoleg.net/lisoleg/elfandlib/
840 * Microsoft%20Portable%20Executable%20COFF%20For
841 * mat%20Specification.txt
842 * for more details.
843 */
844 ms_sym_buf = malloc(sizeof(struct ms_sym) * f_nsyms);
845 if (ms_sym_buf == NULL) {
846 fprintf(stderr, "out of memory\n");
847 exit(1);
848 }
849 fseek(f, f_symptr, SEEK_SET);
850 len = fread(ms_sym_buf, 1,
851 sizeof(struct ms_sym) * f_nsyms, f);
852 sym = (struct ms_sym *) ms_sym_buf;
853 for (sym_nr=0; sym_nr<f_nsyms; sym_nr++) {
854 char name[300];
855 uint32_t v, t, altname;
856 /* debug("sym %5i: '", sym_nr);
857 for (i=0; i<8 && sym->name[i]; i++)
858 debug("%c", sym->name[i]); */
859 v = sym->value[0] + (sym->value[1] << 8)
860 + (sym->value[2] << 16)
861 + (sym->value[3] << 24);
862 altname = sym->name[4] + (sym->name[5] << 8)
863 + (sym->name[6] << 16)
864 + (sym->name[3] << 24);
865 t = (sym->type[1] << 8) + sym->type[0];
866 /* TODO: big endian COFF? */
867 /* debug("' value=0x%x type=0x%04x", v, t); */
868
869 if (t == 0x20 && sym->name[0]) {
870 memcpy(name, sym->name, 8);
871 name[8] = '\0';
872 add_symbol_name(&m->symbol_context,
873 v, 0, name, 0, -1);
874 n_real_symbols ++;
875 } else if (t == 0x20 && !sym->name[0]) {
876 off_t ofs;
877 ofs = f_symptr + altname +
878 sizeof(struct ms_sym) * f_nsyms;
879 fseek(f, ofs, SEEK_SET);
880 fread(name, 1, sizeof(name), f);
881 name[sizeof(name)-1] = '\0';
882 /* debug(" [altname=0x%x '%s']",
883 altname, name); */
884 add_symbol_name(&m->symbol_context,
885 v, 0, name, 0, -1);
886 n_real_symbols ++;
887 }
888
889
890 if (sym->n_aux_syms) {
891 int n = sym->n_aux_syms;
892 /* debug(" aux='"); */
893 while (n-- > 0) {
894 sym ++; sym_nr ++;
895 /* for (i=0; i<8 &&
896 sym->name[i]; i++)
897 debug("%c",
898 sym->name[i]); */
899 }
900 /* debug("'"); */
901 }
902 /* debug("\n"); */
903 sym ++;
904 }
905
906 debug("%i symbols\n", n_real_symbols);
907 free(ms_sym_buf);
908
909 goto skip_normal_coff_symbols;
910 }
911
912 debug("symbol header: magic = 0x%x\n", sym_magic);
913
914 debug("%i symbols @ 0x%08x (strings @ 0x%08x)\n",
915 iextMax, cbExtOffset, cbSsExtOffset);
916
917 symbol_data = malloc(issExtMax + 2);
918 if (symbol_data == NULL) {
919 fprintf(stderr, "out of memory\n");
920 exit(1);
921 }
922 memset(symbol_data, 0, issExtMax + 2);
923 fseek(f, cbSsExtOffset, SEEK_SET);
924 fread(symbol_data, 1, issExtMax + 1, f);
925
926 nsymbols = iextMax;
927
928 extsyms = malloc(iextMax * sizeof(struct ecoff_extsym));
929 if (extsyms == NULL) {
930 fprintf(stderr, "out of memory\n");
931 exit(1);
932 }
933 memset(extsyms, 0, iextMax * sizeof(struct ecoff_extsym));
934 fseek(f, cbExtOffset, SEEK_SET);
935 fread(extsyms, 1, iextMax * sizeof(struct ecoff_extsym), f);
936
937 /* Unencode the strindex and value first: */
938 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
939 uint64_t value, strindex;
940
941 unencode(strindex, &extsyms[sym_nr].es_strindex,
942 uint32_t);
943 unencode(value, &extsyms[sym_nr].es_value, uint32_t);
944
945 extsyms[sym_nr].es_strindex = strindex;
946 extsyms[sym_nr].es_value = value;
947 }
948
949 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
950 /* debug("symbol%6i: 0x%08x = %s\n",
951 sym_nr, (int)extsyms[sym_nr].es_value,
952 symbol_data + extsyms[sym_nr].es_strindex); */
953
954 add_symbol_name(&m->symbol_context,
955 extsyms[sym_nr].es_value, 0,
956 symbol_data + extsyms[sym_nr].es_strindex, 0, -1);
957 }
958
959 free(extsyms);
960 free(symbol_data);
961
962 skip_normal_coff_symbols:
963 ;
964 }
965
966 fclose(f);
967
968 *entrypointp = a_entry;
969 *gpp = a_gp;
970 m->file_loaded_end_addr = end_addr;
971
972 if (program_byte_order != -1)
973 encoding = program_byte_order;
974
975 if (encoding == ELFDATA2LSB)
976 *byte_orderp = EMUL_LITTLE_ENDIAN;
977 else
978 *byte_orderp = EMUL_BIG_ENDIAN;
979
980 n_executables_loaded ++;
981 }
982
983
984 /*
985 * file_load_srec():
986 *
987 * Loads a Motorola SREC file into emulated memory. Description of the SREC
988 * file format can be found at here:
989 *
990 * http://www.ndsu.nodak.edu/instruct/tareski/373f98/notes/srecord.htm
991 * or http://www.amelek.gda.pl/avr/uisp/srecord.htm
992 */
993 static void file_load_srec(struct machine *m, struct memory *mem,
994 char *filename, uint64_t *entrypointp)
995 {
996 FILE *f;
997 unsigned char buf[516];
998 unsigned char bytes[270];
999 uint64_t entry = 0, vaddr = 0;
1000 int i, j, count;
1001 char ch;
1002 int buf_len, data_start = 0;
1003 int entry_set = 0;
1004 int warning = 0;
1005 int warning_len = 0;
1006 int total_bytes_loaded = 0;
1007
1008 f = fopen(filename, "r");
1009 if (f == NULL) {
1010 perror(filename);
1011 exit(1);
1012 }
1013
1014 /* Load file contents: */
1015 while (!feof(f)) {
1016 memset(buf, 0, sizeof(buf));
1017 fgets((char *)buf, sizeof(buf)-1, f);
1018
1019 if (buf[0] == 0 || buf[0]=='\r' || buf[0]=='\n')
1020 continue;
1021
1022 if (buf[0] != 'S') {
1023 if (!warning)
1024 debug("WARNING! non-S-record found\n");
1025 warning = 1;
1026 continue;
1027 }
1028
1029 buf_len = strlen((char *)buf);
1030
1031 if (buf_len < 10) {
1032 if (!warning_len)
1033 debug("WARNING! invalid S-record found\n");
1034 warning_len = 1;
1035 continue;
1036 }
1037
1038 /*
1039 * Stype count address data checksum
1040 * 01 23 4.. .. (last 2 bytes)
1041 *
1042 * TODO: actually check the checksum
1043 */
1044
1045 j = 0;
1046 for (i=1; i<buf_len; i++) {
1047 if (buf[i]>='a' && buf[i]<='f')
1048 buf[i] += 10 - 'a';
1049 else if (buf[i] >= 'A' && buf[i] <= 'F')
1050 buf[i] += 10 - 'A';
1051 else if (buf[i] >= '0' && buf[i] <= '9')
1052 buf[i] -= '0';
1053 else if (buf[i] == '\r' || buf[i] == '\n') {
1054 } else
1055 fatal("invalid characters '%c' in S-record\n",
1056 buf[i]);
1057
1058 if (i >= 4) {
1059 if (i & 1)
1060 bytes[j++] += buf[i];
1061 else
1062 bytes[j] = buf[i] * 16;
1063 }
1064 }
1065
1066 count = buf[2] * 16 + buf[3];
1067 /* debug("count=%i j=%i\n", count, j); */
1068 /* count is j - 1. */
1069
1070 switch (buf[1]) {
1071 case 0:
1072 debug("SREC \"");
1073 for (i=2; i<count-1; i++) {
1074 ch = bytes[i];
1075 if (ch >= ' ' && ch < 127)
1076 debug("%c", ch);
1077 else
1078 debug("?");
1079 }
1080 debug("\"\n");
1081 break;
1082 case 1:
1083 case 2:
1084 case 3:
1085 /* switch again, to get the load address: */
1086 switch (buf[1]) {
1087 case 1: data_start = 2;
1088 vaddr = (bytes[0] << 8) + bytes[1];
1089 break;
1090 case 2: data_start = 3;
1091 vaddr = (bytes[0] << 16) + (bytes[1] << 8) +
1092 bytes[2];
1093 break;
1094 case 3: data_start = 4;
1095 vaddr = (bytes[0] << 24) + (bytes[1] << 16) +
1096 (bytes[2] << 8) + bytes[3];
1097 }
1098 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
1099 &bytes[data_start], count - 1 - data_start,
1100 MEM_WRITE, NO_EXCEPTIONS);
1101 total_bytes_loaded += count - 1 - data_start;
1102 break;
1103 case 7:
1104 case 8:
1105 case 9:
1106 /* switch again, to get the entry point: */
1107 switch (buf[1]) {
1108 case 7: entry = (bytes[0] << 24) + (bytes[1] << 16) +
1109 (bytes[2] << 8) + bytes[3];
1110 break;
1111 case 8: entry = (bytes[0] << 16) + (bytes[1] << 8) +
1112 bytes[2];
1113 break;
1114 case 9: entry = (bytes[0] << 8) + bytes[1];
1115 break;
1116 }
1117 entry_set = 1;
1118 debug("entry point 0x%08x\n", (unsigned int)entry);
1119 break;
1120 default:
1121 debug("unimplemented S-record type %i\n", buf[1]);
1122 }
1123 }
1124
1125 debug("0x%x bytes loaded\n", total_bytes_loaded);
1126
1127 fclose(f);
1128
1129 if (!entry_set)
1130 debug("WARNING! no entrypoint found!\n");
1131 else
1132 *entrypointp = entry;
1133
1134 n_executables_loaded ++;
1135 }
1136
1137
1138 /*
1139 * file_load_raw():
1140 *
1141 * Loads a raw binary into emulated memory. The filename should be
1142 * of the following form: loadaddress:filename
1143 * or loadaddress:skiplen:filename
1144 * or loadaddress:skiplen:pc:filename
1145 */
1146 static void file_load_raw(struct machine *m, struct memory *mem,
1147 char *filename, uint64_t *entrypointp)
1148 {
1149 FILE *f;
1150 int len;
1151 unsigned char buf[4096];
1152 uint64_t entry, loadaddr, vaddr, skip = 0;
1153 char *p, *p2;
1154
1155 p = strchr(filename, ':');
1156 if (p == NULL) {
1157 fprintf(stderr, "\n");
1158 perror(filename);
1159 exit(1);
1160 }
1161
1162 loadaddr = vaddr = entry = strtoull(filename, NULL, 0);
1163 p2 = p+1;
1164
1165 /* A second value? That's the optional skip value */
1166 p = strchr(p2, ':');
1167 if (p != NULL) {
1168 skip = strtoull(p2, NULL, 0);
1169 p = p+1;
1170 /* A third value? That's the initial pc: */
1171 if (strchr(p, ':') != NULL) {
1172 entry = strtoull(p, NULL, 0);
1173 p = strchr(p, ':') + 1;
1174 }
1175 } else
1176 p = p2;
1177
1178 f = fopen(strrchr(filename, ':')+1, "r");
1179 if (f == NULL) {
1180 perror(p);
1181 exit(1);
1182 }
1183
1184 fseek(f, skip, SEEK_SET);
1185
1186 /* Load file contents: */
1187 while (!feof(f)) {
1188 len = fread(buf, 1, sizeof(buf), f);
1189
1190 if (len > 0)
1191 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0],
1192 len, MEM_WRITE, NO_EXCEPTIONS);
1193
1194 vaddr += len;
1195 }
1196
1197 debug("RAW: 0x%llx bytes @ 0x%08llx",
1198 (long long) (ftello(f) - skip), (long long)loadaddr);
1199 if (skip != 0)
1200 debug(" (0x%llx bytes of header skipped)", (long long)skip);
1201 debug("\n");
1202
1203 fclose(f);
1204
1205 *entrypointp = entry;
1206
1207 n_executables_loaded ++;
1208 }
1209
1210
1211 /*
1212 * file_load_elf():
1213 *
1214 * Loads an ELF image into the emulated memory. The entry point (read from
1215 * the ELF header) and the initial value of the gp register (read from the
1216 * ELF symbol table) are stored in the specified CPU's registers.
1217 *
1218 * This is pretty heavy stuff, but is needed because of the heaviness of
1219 * ELF files. :-/ Hopefully it will be able to recognize most valid ELFs.
1220 */
1221 static void file_load_elf(struct machine *m, struct memory *mem,
1222 char *filename, uint64_t *entrypointp, int arch, uint64_t *gpp,
1223 int *byte_order, uint64_t *tocp)
1224 {
1225 Elf32_Ehdr hdr32;
1226 Elf64_Ehdr hdr64;
1227 FILE *f;
1228 uint64_t eentry;
1229 int len, i, ok;
1230 int elf64, encoding, eflags;
1231 int etype, emachine;
1232 int ephnum, ephentsize, eshnum, eshentsize;
1233 off_t ephoff, eshoff;
1234 Elf32_Phdr phdr32;
1235 Elf64_Phdr phdr64;
1236 Elf32_Shdr shdr32;
1237 Elf64_Shdr shdr64;
1238 Elf32_Sym sym32;
1239 Elf64_Sym sym64;
1240 int ofs;
1241 int chunk_len = 1024, align_len;
1242 char *symbol_strings = NULL; size_t symbol_length = 0;
1243 char *s;
1244 Elf32_Sym *symbols_sym32 = NULL; int n_symbols = 0;
1245 Elf64_Sym *symbols_sym64 = NULL;
1246
1247 f = fopen(filename, "r");
1248 if (f == NULL) {
1249 perror(filename);
1250 exit(1);
1251 }
1252
1253 len = fread(&hdr32, 1, sizeof(Elf32_Ehdr), f);
1254 if (len < (signed int)sizeof(Elf32_Ehdr)) {
1255 fprintf(stderr, "%s: not an ELF file image\n", filename);
1256 exit(1);
1257 }
1258
1259 if (memcmp(&hdr32.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) {
1260 fprintf(stderr, "%s: not an ELF file image\n", filename);
1261 exit(1);
1262 }
1263
1264 switch (hdr32.e_ident[EI_CLASS]) {
1265 case ELFCLASS32:
1266 elf64 = 0;
1267 break;
1268 case ELFCLASS64:
1269 elf64 = 1;
1270 fseek(f, 0, SEEK_SET);
1271 len = fread(&hdr64, 1, sizeof(Elf64_Ehdr), f);
1272 if (len < (signed int)sizeof(Elf64_Ehdr)) {
1273 fprintf(stderr, "%s: not an ELF64 file image\n",
1274 filename);
1275 exit(1);
1276 }
1277 break;
1278 default:
1279 fprintf(stderr, "%s: unknown ELF class '%i'\n",
1280 filename, hdr32.e_ident[EI_CLASS]);
1281 exit(1);
1282 }
1283
1284 encoding = hdr32.e_ident[EI_DATA];
1285 if (encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) {
1286 fprintf(stderr, "%s: unknown data encoding '%i'\n",
1287 filename, hdr32.e_ident[EI_DATA]);
1288 exit(1);
1289 }
1290
1291 if (elf64) {
1292 unencode(etype, &hdr64.e_type, Elf64_Quarter);
1293 unencode(eflags, &hdr64.e_flags, Elf64_Half);
1294 unencode(emachine, &hdr64.e_machine, Elf64_Quarter);
1295 unencode(eentry, &hdr64.e_entry, Elf64_Addr);
1296 unencode(ephnum, &hdr64.e_phnum, Elf64_Quarter);
1297 unencode(ephentsize, &hdr64.e_phentsize, Elf64_Quarter);
1298 unencode(ephoff, &hdr64.e_phoff, Elf64_Off);
1299 unencode(eshnum, &hdr64.e_shnum, Elf64_Quarter);
1300 unencode(eshentsize, &hdr64.e_shentsize, Elf64_Quarter);
1301 unencode(eshoff, &hdr64.e_shoff, Elf64_Off);
1302 if (ephentsize != sizeof(Elf64_Phdr)) {
1303 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1304 "be %i\nPerhaps this is a dynamically linked "
1305 "binary (which isn't supported yet).\n", filename,
1306 (int)ephentsize, (int)sizeof(Elf64_Phdr));
1307 exit(1);
1308 }
1309 if (eshentsize != sizeof(Elf64_Shdr)) {
1310 fprintf(stderr, "%s: incorrect shentsize? %i, should "
1311 "be %i\nPerhaps this is a dynamically linked "
1312 "binary (which isn't supported yet).\n", filename,
1313 (int)eshentsize, (int)sizeof(Elf64_Shdr));
1314 exit(1);
1315 }
1316 } else {
1317 unencode(etype, &hdr32.e_type, Elf32_Half);
1318 unencode(eflags, &hdr32.e_flags, Elf32_Word);
1319 unencode(emachine, &hdr32.e_machine, Elf32_Half);
1320 unencode(eentry, &hdr32.e_entry, Elf32_Addr);
1321 unencode(ephnum, &hdr32.e_phnum, Elf32_Half);
1322 unencode(ephentsize, &hdr32.e_phentsize, Elf32_Half);
1323 unencode(ephoff, &hdr32.e_phoff, Elf32_Off);
1324 unencode(eshnum, &hdr32.e_shnum, Elf32_Half);
1325 unencode(eshentsize, &hdr32.e_shentsize, Elf32_Half);
1326 unencode(eshoff, &hdr32.e_shoff, Elf32_Off);
1327 if (ephentsize != sizeof(Elf32_Phdr)) {
1328 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1329 "be %i\nPerhaps this is a dynamically linked "
1330 "binary (which isn't supported yet).\n", filename,
1331 (int)ephentsize, (int)sizeof(Elf32_Phdr));
1332 exit(1);
1333 }
1334 if (eshentsize != sizeof(Elf32_Shdr)) {
1335 fprintf(stderr, "%s: incorrect shentsize? %i, should "
1336 "be %i\nPerhaps this is a dynamically linked "
1337 "binary (which isn't supported yet).\n", filename,
1338 (int)eshentsize, (int)sizeof(Elf32_Shdr));
1339 exit(1);
1340 }
1341 }
1342
1343 if ( etype != ET_EXEC ) {
1344 fprintf(stderr, "%s is not an ELF Executable file, type = %i\n",
1345 filename, etype);
1346 exit(1);
1347 }
1348
1349 ok = 0;
1350 switch (arch) {
1351 case ARCH_ALPHA:
1352 switch (emachine) {
1353 case EM_ALPHA:
1354 case -28634:
1355 ok = 1;
1356 }
1357 break;
1358 case ARCH_ARM:
1359 switch (emachine) {
1360 case EM_ARM:
1361 ok = 1;
1362 }
1363 break;
1364 case ARCH_AVR:
1365 switch (emachine) {
1366 case EM_AVR:
1367 ok = 1;
1368 }
1369 break;
1370 case ARCH_HPPA:
1371 switch (emachine) {
1372 case EM_PARISC:
1373 ok = 1;
1374 }
1375 break;
1376 case ARCH_I960:
1377 switch (emachine) {
1378 case EM_960:
1379 ok = 1;
1380 }
1381 break;
1382 case ARCH_IA64:
1383 switch (emachine) {
1384 case EM_IA_64:
1385 ok = 1;
1386 }
1387 break;
1388 case ARCH_M68K:
1389 switch (emachine) {
1390 case EM_68K:
1391 ok = 1;
1392 }
1393 break;
1394 case ARCH_MIPS:
1395 switch (emachine) {
1396 case EM_MIPS:
1397 case EM_MIPS_RS3_LE:
1398 ok = 1;
1399 }
1400 break;
1401 case ARCH_PPC:
1402 switch (emachine) {
1403 case EM_PPC:
1404 case EM_PPC64:
1405 ok = 1;
1406 }
1407 break;
1408 case ARCH_SH:
1409 switch (emachine) {
1410 case EM_SH:
1411 ok = 1;
1412 }
1413 break;
1414 case ARCH_SPARC:
1415 switch (emachine) {
1416 case EM_SPARC:
1417 case EM_SPARCV9:
1418 ok = 1;
1419 }
1420 break;
1421 case ARCH_X86:
1422 switch (emachine) {
1423 case EM_386:
1424 case EM_486:
1425 *tocp = 1;
1426 ok = 1;
1427 break;
1428 case EM_AMD64:
1429 *tocp = 2;
1430 ok = 1;
1431 break;
1432 }
1433 break;
1434 default:
1435 fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
1436 }
1437 if (!ok) {
1438 fprintf(stderr, "%s: this is a ", filename);
1439 if (emachine >= 0 && emachine < N_ELF_MACHINE_TYPES)
1440 fprintf(stderr, elf_machine_type[emachine]);
1441 else
1442 fprintf(stderr, "machine type '%i'", emachine);
1443 fprintf(stderr, " ELF binary!\n");
1444 exit(1);
1445 }
1446
1447 s = "entry point";
1448 if (elf64 && arch == ARCH_PPC)
1449 s = "function descriptor at";
1450
1451 debug("ELF%i %s, %s 0x", elf64? 64 : 32,
1452 encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
1453
1454 if (elf64)
1455 debug("%016llx\n", (long long)eentry);
1456 else
1457 debug("%08x\n", (int)eentry);
1458
1459 /*
1460 * MIPS16 encoding?
1461 *
1462 * TODO: Find out what e_flag actually contains.
1463 * TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!
1464 */
1465 if (arch == ARCH_MIPS && ((eflags >> 24) & 0xff) == 0x24) {
1466 debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);
1467 #ifdef ENABLE_MIPS16
1468 m->cpus[0]->cd.mips.mips16 = 1;
1469 #else
1470 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1471 "(or use the --mips16 configure option)\n");
1472 exit(1);
1473 #endif
1474 } else if (arch == ARCH_MIPS && (eentry & 0x3)) {
1475 debug("MIPS16 encoding (eentry not 32-bit aligned)\n");
1476 #ifdef ENABLE_MIPS16
1477 m->cpus[0]->cd.mips.mips16 = 1;
1478 #else
1479 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1480 "(or use the --mips16 configure option)\n");
1481 exit(1);
1482 #endif
1483 }
1484
1485 /*
1486 * SH64: 32-bit instruction encoding? TODO
1487 */
1488 if (arch == ARCH_SH && (eentry & 1)) {
1489 debug("SH64: 32-bit instruction encoding\n");
1490 m->cpus[0]->cd.sh.compact = 0;
1491 m->cpus[0]->cd.sh.bits = 64;
1492 }
1493
1494 /* Read the program headers: */
1495
1496 for (i=0; i<ephnum; i++) {
1497 int p_type;
1498 uint64_t p_offset;
1499 uint64_t p_vaddr;
1500 uint64_t p_paddr;
1501 uint64_t p_filesz;
1502 uint64_t p_memsz;
1503 int p_flags;
1504 int p_align;
1505
1506 fseek(f, ephoff + i * ephentsize, SEEK_SET);
1507
1508 if (elf64) {
1509 fread(&phdr64, 1, sizeof(Elf64_Phdr), f);
1510 unencode(p_type, &phdr64.p_type, Elf64_Half);
1511 unencode(p_flags, &phdr64.p_flags, Elf64_Half);
1512 unencode(p_offset, &phdr64.p_offset, Elf64_Off);
1513 unencode(p_vaddr, &phdr64.p_vaddr, Elf64_Addr);
1514 unencode(p_paddr, &phdr64.p_paddr, Elf64_Addr);
1515 unencode(p_filesz, &phdr64.p_filesz, Elf64_Xword);
1516 unencode(p_memsz, &phdr64.p_memsz, Elf64_Xword);
1517 unencode(p_align, &phdr64.p_align, Elf64_Xword);
1518 } else {
1519 fread(&phdr32, 1, sizeof(Elf32_Phdr), f);
1520 unencode(p_type, &phdr32.p_type, Elf32_Word);
1521 unencode(p_offset, &phdr32.p_offset, Elf32_Off);
1522 unencode(p_vaddr, &phdr32.p_vaddr, Elf32_Addr);
1523 unencode(p_paddr, &phdr32.p_paddr, Elf32_Addr);
1524 unencode(p_filesz, &phdr32.p_filesz, Elf32_Word);
1525 unencode(p_memsz, &phdr32.p_memsz, Elf32_Word);
1526 unencode(p_flags, &phdr32.p_flags, Elf32_Word);
1527 unencode(p_align, &phdr32.p_align, Elf32_Word);
1528 }
1529
1530 if (p_memsz != 0 && (p_type == PT_LOAD ||
1531 (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1532 debug("chunk %i (", i);
1533 if (p_type == PT_LOAD)
1534 debug("load");
1535 else
1536 debug("0x%08x", (int)p_type);
1537
1538 debug(") @ 0x%llx, vaddr 0x", (long long)p_offset);
1539
1540 if (elf64)
1541 debug("%016llx", (long long)p_vaddr);
1542 else
1543 debug("%08x", (int)p_vaddr);
1544
1545 debug(" len=0x%llx\n", (long long)p_memsz);
1546
1547 if (p_vaddr != p_paddr)
1548 fatal("WARNING! vaddr (0x%llx) and paddr "
1549 "(0x%llx) differ; using vaddr\n",
1550 (long long)p_vaddr, (long long)p_paddr);
1551
1552 if (p_memsz < p_filesz) {
1553 fprintf(stderr, "%s: memsz < filesz. TODO: how"
1554 " to handle this? memsz=%016llx filesz="
1555 "%016llx\n", filename, (long long)p_memsz,
1556 (long long)p_filesz);
1557 exit(1);
1558 }
1559
1560 fseek(f, p_offset, SEEK_SET);
1561 align_len = 1;
1562 if ((p_vaddr & 0xf)==0) align_len = 0x10;
1563 if ((p_vaddr & 0x3f)==0) align_len = 0x40;
1564 if ((p_vaddr & 0xff)==0) align_len = 0x100;
1565 if ((p_vaddr & 0xfff)==0) align_len = 0x1000;
1566 if ((p_vaddr & 0x3fff)==0) align_len = 0x4000;
1567 if ((p_vaddr & 0xffff)==0) align_len = 0x10000;
1568 ofs = 0; len = chunk_len = align_len;
1569 while (ofs < (int64_t)p_filesz && len==chunk_len) {
1570 unsigned char *ch = malloc(chunk_len);
1571 int i = 0;
1572
1573 /* Switch to larger size, if possible: */
1574 if (align_len < 0x10000 &&
1575 ((p_vaddr + ofs) & 0xffff)==0) {
1576 align_len = 0x10000;
1577 len = chunk_len = align_len;
1578 free(ch);
1579 ch = malloc(chunk_len);
1580 } else if (align_len < 0x1000 &&
1581 ((p_vaddr + ofs) & 0xfff)==0) {
1582 align_len = 0x1000;
1583 len = chunk_len = align_len;
1584 free(ch);
1585 ch = malloc(chunk_len);
1586 }
1587
1588 if (ch == NULL) {
1589 fprintf(stderr, "out of memory\n");
1590 exit(1);
1591 }
1592
1593 len = fread(&ch[0], 1, chunk_len, f);
1594 if (ofs + len > (int64_t)p_filesz)
1595 len = p_filesz - ofs;
1596
1597 while (i < len) {
1598 size_t len_to_copy;
1599 len_to_copy = (i + align_len) <= len?
1600 align_len : len - i;
1601 m->cpus[0]->memory_rw(m->cpus[0], mem,
1602 p_vaddr + ofs, &ch[i], len_to_copy,
1603 MEM_WRITE, NO_EXCEPTIONS);
1604 ofs += align_len;
1605 i += align_len;
1606 }
1607
1608 free(ch);
1609 }
1610 }
1611 }
1612
1613 /*
1614 * Read the section headers to find the address of the _gp
1615 * symbol (for MIPS):
1616 */
1617
1618 for (i=0; i<eshnum; i++) {
1619 int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
1620 uint64_t sh_addr, sh_size, sh_addralign;
1621 off_t sh_offset;
1622 int n_entries; /* for reading the symbol / string tables */
1623
1624 /* debug("section header %i at %016llx\n", i,
1625 (long long) eshoff+i*eshentsize); */
1626
1627 fseek(f, eshoff + i * eshentsize, SEEK_SET);
1628
1629 if (elf64) {
1630 len = fread(&shdr64, 1, sizeof(Elf64_Shdr), f);
1631 if (len != sizeof(Elf64_Shdr)) {
1632 fprintf(stderr, "couldn't read header\n");
1633 exit(1);
1634 }
1635 unencode(sh_name, &shdr64.sh_name, Elf64_Half);
1636 unencode(sh_type, &shdr64.sh_type, Elf64_Half);
1637 unencode(sh_flags, &shdr64.sh_flags, Elf64_Xword);
1638 unencode(sh_addr, &shdr64.sh_addr, Elf64_Addr);
1639 unencode(sh_offset, &shdr64.sh_offset, Elf64_Off);
1640 unencode(sh_size, &shdr64.sh_size, Elf64_Xword);
1641 unencode(sh_link, &shdr64.sh_link, Elf64_Half);
1642 unencode(sh_info, &shdr64.sh_info, Elf64_Half);
1643 unencode(sh_addralign, &shdr64.sh_addralign,
1644 Elf64_Xword);
1645 unencode(sh_entsize, &shdr64.sh_entsize, Elf64_Xword);
1646 } else {
1647 len = fread(&shdr32, 1, sizeof(Elf32_Shdr), f);
1648 if (len != sizeof(Elf32_Shdr)) {
1649 fprintf(stderr, "couldn't read header\n");
1650 exit(1);
1651 }
1652 unencode(sh_name, &shdr32.sh_name, Elf32_Word);
1653 unencode(sh_type, &shdr32.sh_type, Elf32_Word);
1654 unencode(sh_flags, &shdr32.sh_flags, Elf32_Word);
1655 unencode(sh_addr, &shdr32.sh_addr, Elf32_Addr);
1656 unencode(sh_offset, &shdr32.sh_offset, Elf32_Off);
1657 unencode(sh_size, &shdr32.sh_size, Elf32_Word);
1658 unencode(sh_link, &shdr32.sh_link, Elf32_Word);
1659 unencode(sh_info, &shdr32.sh_info, Elf32_Word);
1660 unencode(sh_addralign, &shdr32.sh_addralign,Elf32_Word);
1661 unencode(sh_entsize, &shdr32.sh_entsize, Elf32_Word);
1662 }
1663
1664 /* debug("sh_name=%04lx, sh_type=%08lx, sh_flags=%08lx"
1665 " sh_size=%06lx sh_entsize=%03lx\n",
1666 (long)sh_name, (long)sh_type, (long)sh_flags,
1667 (long)sh_size, (long)sh_entsize); */
1668
1669 /* Perhaps it is bad to reuse sh_entsize like this? TODO */
1670 if (elf64)
1671 sh_entsize = sizeof(Elf64_Sym);
1672 else
1673 sh_entsize = sizeof(Elf32_Sym);
1674
1675 if (sh_type == SHT_SYMTAB) {
1676 size_t len;
1677 n_entries = sh_size / sh_entsize;
1678
1679 fseek(f, sh_offset, SEEK_SET);
1680
1681 if (elf64) {
1682 if (symbols_sym64 != NULL)
1683 free(symbols_sym64);
1684 symbols_sym64 = malloc(sh_size);
1685 if (symbols_sym64 == NULL) {
1686 fprintf(stderr, "out of memory\n");
1687 exit(1);
1688 }
1689
1690 len = fread(symbols_sym64, 1, sh_entsize *
1691 n_entries, f);
1692 } else {
1693 if (symbols_sym32 != NULL)
1694 free(symbols_sym32);
1695 symbols_sym32 = malloc(sh_size);
1696 if (symbols_sym32 == NULL) {
1697 fprintf(stderr, "out of memory\n");
1698 exit(1);
1699 }
1700
1701 len = fread(symbols_sym32, 1,
1702 sh_entsize * n_entries, f);
1703 }
1704
1705 if (len != sh_size) {
1706 fprintf(stderr, "could not read symbols from "
1707 "%s\n", filename);
1708 exit(1);
1709 }
1710
1711 debug("%i symbol entries at 0x%llx\n",
1712 (int)n_entries, (long long)sh_offset);
1713
1714 n_symbols = n_entries;
1715 }
1716
1717 /*
1718 * TODO: This is incorrect, there may be several strtab
1719 * sections.
1720 *
1721 * For now, the simple/stupid guess that the largest string
1722 * table is the one to use seems to be good enough.
1723 */
1724
1725 if (sh_type == SHT_STRTAB && sh_size > symbol_length) {
1726 size_t len;
1727
1728 if (symbol_strings != NULL)
1729 free(symbol_strings);
1730
1731 symbol_strings = malloc(sh_size + 1);
1732 if (symbol_strings == NULL) {
1733 fprintf(stderr, "out of memory\n");
1734 exit(1);
1735 }
1736
1737 fseek(f, sh_offset, SEEK_SET);
1738 len = fread(symbol_strings, 1, sh_size, f);
1739 if (len != sh_size) {
1740 fprintf(stderr, "could not read symbols from "
1741 "%s\n", filename);
1742 exit(1);
1743 }
1744
1745 debug("%i bytes of symbol strings at 0x%llx\n",
1746 (int)sh_size, (long long)sh_offset);
1747
1748 symbol_strings[sh_size] = '\0';
1749 symbol_length = sh_size;
1750 }
1751 }
1752
1753 fclose(f);
1754
1755 /* Decode symbols: */
1756 if (symbol_strings != NULL) {
1757 for (i=0; i<n_symbols; i++) {
1758 uint64_t st_name, addr, size;
1759 int st_info;
1760
1761 if (elf64) {
1762 sym64 = symbols_sym64[i];
1763 unencode(st_name, &sym64.st_name, Elf64_Half);
1764 unencode(st_info, &sym64.st_info, Elf_Byte);
1765 unencode(addr, &sym64.st_value, Elf64_Addr);
1766 unencode(size, &sym64.st_size, Elf64_Xword);
1767 } else {
1768 sym32 = symbols_sym32[i];
1769 unencode(st_name, &sym32.st_name, Elf32_Word);
1770 unencode(st_info, &sym64.st_info, Elf_Byte);
1771 unencode(addr, &sym32.st_value, Elf32_Word);
1772 unencode(size, &sym32.st_size, Elf32_Word);
1773 }
1774
1775 /* debug("symbol info=0x%02x addr=0x%016llx"
1776 " (%i) '%s'\n", st_info, (long long)addr,
1777 st_name, symbol_strings + st_name); */
1778
1779 if (size == 0)
1780 size ++;
1781
1782 if (addr != 0) /* && ((st_info >> 4) & 0xf)
1783 >= STB_GLOBAL) */ {
1784 /* debug("symbol info=0x%02x addr=0x%016llx"
1785 " '%s'\n", st_info, (long long)addr,
1786 symbol_strings + st_name); */
1787 add_symbol_name(&m->symbol_context,
1788 addr, size, symbol_strings + st_name,
1789 0, -1);
1790 }
1791
1792 if (strcmp(symbol_strings + st_name, "_gp") == 0) {
1793 debug("found _gp address: 0x");
1794 if (elf64)
1795 debug("%016llx\n", (long long)addr);
1796 else
1797 debug("%08x\n", (int)addr);
1798 *gpp = addr;
1799 }
1800 }
1801 }
1802
1803 *entrypointp = eentry;
1804
1805 if (encoding == ELFDATA2LSB)
1806 *byte_order = EMUL_LITTLE_ENDIAN;
1807 else
1808 *byte_order = EMUL_BIG_ENDIAN;
1809
1810 if (elf64 && arch == ARCH_PPC) {
1811 /*
1812 * Special case for 64-bit PPC ELFs:
1813 *
1814 * The ELF starting symbol points to a ".opd" section
1815 * which contains a function descriptor:
1816 *
1817 * uint64_t start;
1818 * uint64_t toc_base;
1819 * uint64_t something_else; (?)
1820 */
1821 int res;
1822 unsigned char b[sizeof(uint64_t)];
1823 uint64_t toc_base;
1824
1825 debug("PPC64: ");
1826
1827 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry, b,
1828 sizeof(b), MEM_READ, NO_EXCEPTIONS);
1829 if (!res)
1830 debug(" [WARNING: could not read memory?] ");
1831
1832 /* PPC are always big-endian: */
1833 *entrypointp = ((uint64_t)b[0] << 56) +
1834 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1835 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1836 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1837 (uint64_t)b[7];
1838
1839 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry + 8,
1840 b, sizeof(b), MEM_READ, NO_EXCEPTIONS);
1841 if (!res)
1842 fatal(" [WARNING: could not read memory?] ");
1843
1844 toc_base = ((uint64_t)b[0] << 56) +
1845 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1846 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1847 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1848 (uint64_t)b[7];
1849
1850 debug("entrypoint 0x%016llx, toc_base 0x%016llx\n",
1851 (long long)*entrypointp, (long long)toc_base);
1852 if (tocp != NULL)
1853 *tocp = toc_base;
1854 }
1855
1856 n_executables_loaded ++;
1857 }
1858
1859
1860 /*
1861 * file_n_executables_loaded():
1862 *
1863 * Returns the number of executable files loaded into emulated memory.
1864 */
1865 int file_n_executables_loaded(void)
1866 {
1867 return n_executables_loaded;
1868 }
1869
1870
1871 /*
1872 * file_load():
1873 *
1874 * Sense the file format of a file (ELF, a.out, ecoff), and call the
1875 * right file_load_XXX() function. If the file isn't of a recognized
1876 * binary format, assume that it contains symbol definitions.
1877 *
1878 * If the filename doesn't exist, try to treat the name as
1879 * "address:filename" and load the file as a raw binary.
1880 */
1881 void file_load(struct machine *machine, struct memory *mem,
1882 char *filename, uint64_t *entrypointp,
1883 int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)
1884 {
1885 int iadd = 4;
1886 FILE *f;
1887 unsigned char buf[12];
1888 unsigned char buf2[2];
1889 size_t len, len2, i;
1890 off_t size;
1891
1892 if (byte_orderp == NULL) {
1893 fprintf(stderr, "file_load(): byte_order == NULL\n");
1894 exit(1);
1895 }
1896
1897 if (arch == ARCH_NOARCH) {
1898 fprintf(stderr, "file_load(): FATAL ERROR: no arch?\n");
1899 exit(1);
1900 }
1901
1902 if (mem == NULL || filename == NULL) {
1903 fprintf(stderr, "file_load(): mem or filename is NULL\n");
1904 exit(1);
1905 }
1906
1907 /* Skip configuration files: */
1908 if (filename[0] == '@')
1909 return;
1910
1911 debug("loading %s:\n", filename);
1912 debug_indentation(iadd);
1913
1914 f = fopen(filename, "r");
1915 if (f == NULL) {
1916 file_load_raw(machine, mem, filename, entrypointp);
1917 goto ret;
1918 }
1919
1920 fseek(f, 0, SEEK_END);
1921 size = ftello(f);
1922 fseek(f, 0, SEEK_SET);
1923
1924 memset(buf, 0, sizeof(buf));
1925 len = fread(buf, 1, sizeof(buf), f);
1926 fseek(f, 510, SEEK_SET);
1927 len2 = fread(buf2, 1, sizeof(buf2), f);
1928 fclose(f);
1929
1930 if (len < (signed int)sizeof(buf)) {
1931 fprintf(stderr, "\nThis file is too small to contain "
1932 "anything useful\n");
1933 exit(1);
1934 }
1935
1936 /* Is it an ELF? */
1937 if (buf[0] == 0x7f && buf[1]=='E' && buf[2]=='L' && buf[3]=='F') {
1938 file_load_elf(machine, mem, filename,
1939 entrypointp, arch, gpp, byte_orderp, tocp);
1940 goto ret;
1941 }
1942
1943 /* Is it an a.out? */
1944 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1945 /* MIPS a.out */
1946 file_load_aout(machine, mem, filename, 0,
1947 entrypointp, arch, byte_orderp);
1948 goto ret;
1949 }
1950 if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
1951 /* M68K a.out */
1952 file_load_aout(machine, mem, filename,
1953 AOUT_FLAG_VADDR_ZERO_HACK /* for OpenBSD/mac68k */,
1954 entrypointp, arch, byte_orderp);
1955 goto ret;
1956 }
1957 if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
1958 /* ARM a.out */
1959 file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1960 entrypointp, arch, byte_orderp);
1961 goto ret;
1962 }
1963 if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
1964 /* i386 a.out (old OpenBSD and NetBSD etc) */
1965 file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1966 entrypointp, arch, byte_orderp);
1967 goto ret;
1968 }
1969 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
1970 /* DEC OSF1 on MIPS: */
1971 file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
1972 entrypointp, arch, byte_orderp);
1973 goto ret;
1974 }
1975
1976 /*
1977 * Is it a Mach-O file?
1978 */
1979 if (buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa &&
1980 (buf[3] == 0xce || buf[3] == 0xcf)) {
1981 file_load_macho(machine, mem, filename, entrypointp,
1982 arch, byte_orderp, buf[3] == 0xcf, 0);
1983 goto ret;
1984 }
1985 if ((buf[0] == 0xce || buf[0] == 0xcf) && buf[1] == 0xfa &&
1986 buf[2] == 0xed && buf[3] == 0xfe) {
1987 file_load_macho(machine, mem, filename, entrypointp,
1988 arch, byte_orderp, buf[0] == 0xcf, 1);
1989 goto ret;
1990 }
1991
1992 /*
1993 * Is it an ecoff?
1994 *
1995 * TODO: What's the deal with the magic value's byte order? Sometimes
1996 * it seems to be reversed for BE when compared to LE, but not always?
1997 */
1998 if (buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB ||
1999 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL ||
2000 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB2 ||
2001 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL2 ||
2002 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB3 ||
2003 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL3 ||
2004 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB ||
2005 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL ||
2006 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB2 ||
2007 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL2 ||
2008 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB3 ||
2009 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL3) {
2010 file_load_ecoff(machine, mem, filename, entrypointp,
2011 arch, gpp, byte_orderp);
2012 goto ret;
2013 }
2014
2015 /* Is it a Motorola SREC file? */
2016 if ((buf[0]=='S' && buf[1]>='0' && buf[1]<='9')) {
2017 file_load_srec(machine, mem, filename, entrypointp);
2018 goto ret;
2019 }
2020
2021 /* gzipped files are not supported: */
2022 if (buf[0]==0x1f && buf[1]==0x8b) {
2023 fprintf(stderr, "\nYou need to gunzip the file before you"
2024 " try to use it.\n");
2025 exit(1);
2026 }
2027
2028 if (size > 24000000) {
2029 fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
2030 (long long)size);
2031 fprintf(stderr, "Are you sure it is a kernel and not a disk "
2032 "image? (Use the -d option.)\n");
2033 exit(1);
2034 }
2035
2036 if (size == 1474560)
2037 fprintf(stderr, "Hm... this file is the size of a 1.44 MB "
2038 "floppy image. Maybe you forgot the\n-d switch?\n");
2039
2040 /*
2041 * Last resort: symbol definitions from nm (or nm -S):
2042 *
2043 * If the buf contains typical 'binary' characters, then print
2044 * an error message and quit instead of assuming that it is a
2045 * symbol file.
2046 */
2047 for (i=0; i<(signed)sizeof(buf); i++)
2048 if (buf[i] < 32 && buf[i] != '\t' &&
2049 buf[i] != '\n' && buf[i] != '\r' &&
2050 buf[i] != '\f') {
2051 fprintf(stderr, "\nThe file format of '%s' is "
2052 "unknown.\n\n ", filename);
2053 for (i=0; i<(signed)sizeof(buf); i++)
2054 fprintf(stderr, " %02x", buf[i]);
2055
2056 if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
2057 fprintf(stderr, "\n\nIt has a PC-style "
2058 "bootsector marker.");
2059
2060 fprintf(stderr, "\n\nPossible explanations:\n\n"
2061 " o) If this is a disk image, you forgot '-d' "
2062 "on the command line.\n"
2063 " o) This is an unsupported binary format.\n\n");
2064 exit(1);
2065 }
2066
2067 symbol_readfile(&machine->symbol_context, filename);
2068
2069 ret:
2070 debug_indentation(-iadd);
2071 }
2072

  ViewVC Help
Powered by ViewVC 1.1.26