/[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 24 - (show annotations)
Mon Oct 8 16:19:56 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 57533 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1256 2006/06/23 20:43:44 debug Exp $
20060219	Various minor updates. Removing the old MIPS16 skeleton code,
		because it will need to be rewritten for dyntrans anyway.
20060220-22	Removing the non-working dyntrans backend support.
		Continuing on the 64-bit dyntrans virtual memory generalization.
20060223	More work on the 64-bit vm generalization.
20060225	Beginning on MIPS dyntrans load/store instructions.
		Minor PPC updates (64-bit load/store, etc).
		Fixes for the variable-instruction-length framework, some
		minor AVR updates (a simple Hello World program works!).
		Beginning on a skeleton for automatically generating documen-
		tation (for devices etc.).
20060226	PPC updates (adding some more 64-bit instructions, etc).
		AVR updates (more instructions).
		FINALLY found and fixed the zs bug, making NetBSD/macppc
		accept the serial console.
20060301	Adding more AVR instructions.
20060304	Continuing on AVR-related stuff. Beginning on a framework for
		cycle-accurate device emulation. Adding an experimental "PAL
		TV" device (just a dummy so far).
20060305	Adding more AVR instructions.
		Adding a dummy epcom serial controller (for TS7200 emulation).
20060310	Removing the emul() command from configuration files, so only
		net() and machine() are supported.
		Minor progress on the MIPS dyntrans rewrite.
20060311	Continuing on the MIPS dyntrans rewrite (adding more
		instructions, etc).
20060315	Adding more instructions (sllv, srav, srlv, bgtz[l], blez[l],
		beql, bnel, slti[u], various loads and stores).
20060316	Removing the ALWAYS_SIGNEXTEND_32 option, since it was rarely
		used.
		Adding more MIPS dyntrans instructions, and fixing bugs.
20060318	Implementing fast loads/stores for MIPS dyntrans (big/little
		endian, 32-bit and 64-bit modes).
20060320	Making MIPS dyntrans the default configure option; use
		"--enable-oldmips" to use the old bintrans system.
		Adding MIPS dyntrans dmult[u]; minor updates.
20060322	Continuing... adding some more instructions.
		Adding a simple skeleton for demangling C++ "_ZN" symbols.
20060323	Moving src/debugger.c into a new directory (src/debugger/).
20060324	Fixing the hack used to load PPC ELFs (useful for relocated
		Linux/ppc kernels), and adding a dummy G3 machine mode.
20060325-26	Beginning to experiment with GDB remote serial protocol
		connections; adding a -G command line option for selecting
		which TCP port to listen to.
20060330	Beginning a major cleanup to replace things like "0x%016llx"
		with more correct "0x%016"PRIx64, etc.
		Continuing on the GDB remote serial protocol support.
20060331	More cleanup, and some minor GDB remote progress.
20060402	Adding a hack to the configure script, to allow compilation
		on systems that lack PRIx64 etc.
20060406	Removing the temporary FreeBSD/arm hack in dev_ns16550.c and
		replacing it with a better fix from Olivier Houchard.
20060407	A remote debugger (gdb or ddd) can now start and stop the
		emulator using the GDB remote serial protocol, and registers
		and memory can be read. MIPS only for now.
20060408	More GDB progress: single-stepping also works, and also adding
		support for ARM, PowerPC, and Alpha targets.
		Continuing on the delay-slot-across-page-boundary issue.
20060412	Minor update: beginning to add support for the SPARC target
		to the remote GDB functionality.
20060414	Various MIPS updates: adding more instructions for dyntrans
		(eret, add), and making some exceptions work. Fixing a bug
		in dmult[u].
		Implementing the first SPARC instructions (sethi, or).
20060415	Adding "magic trap" instructions so that PROM calls can be
		software emulated in MIPS dyntrans.
		Adding more MIPS dyntrans instructions (ddiv, dadd) and
		fixing another bug in dmult.
20060416	More MIPS dyntrans progress: adding [d]addi, movn, movz, dsllv,
		rfi, an ugly hack for supporting R2000/R3000 style faked caches,
		preliminary interrupt support, and various other updates and
		bugfixes.
20060417	Adding more SPARC instructions (add, sub, sll[x], sra[x],
		srl[x]), and useful SPARC header definitions.
		Adding the first (trivial) x86/AMD64 dyntrans instructions (nop,
		cli/sti, stc/clc, std/cld, simple mov, inc ax). Various other
		x86 updates related to variable instruction length stuff.
		Adding unaligned loads/stores to the MIPS dyntrans mode (but
		still using the pre-dyntrans (slow) imlementation).
20060419	Fixing a MIPS dyntrans exception-in-delay-slot bug.
		Removing the old "show opcode statistics" functionality, since
		it wasn't really useful and isn't implemented for dyntrans.
		Single-stepping (or running with instruction trace) now looks
		ok with dyntrans with delay-slot architectures.
20060420	Minor hacks (removing the -B command line option when compiled
		for non-bintrans, and some other very minor updates).
		Adding (slow) MIPS dyntrans load-linked/store-conditional.
20060422	Applying fixes for bugs discovered by Nils Weller's nwcc
		(static DEC memmap => now per machine, and adding an extern
		keyword in cpu_arm_instr.c).
		Finally found one of the MIPS dyntrans bugs that I've been
		looking for (copy/paste spelling error BIG vs LITTLE endian in
		cpu_mips_instr_loadstore.c for 16-bit fast stores).
		FINALLY found the major MIPS dyntrans bug: slti vs sltiu
		signed/unsigned code in cpu_mips_instr.c. :-)
		Adding more MIPS dyntrans instructions (lwc1, swc1, bgezal[l],
		ctc1, tlt[u], tge[u], tne, beginning on rdhwr).
		NetBSD/hpcmips can now reach userland when using dyntrans :-)
		Adding some more x86 dyntrans instructions.
		Finally removed the old Alpha-specific virtual memory code,
		and replaced it with the generic 64-bit version.
		Beginning to add disassembly support for SPECIAL3 MIPS opcodes.
20060423	Continuing on the delay-slot-across-page-boundary issue;
		adding an end_of_page2 ic slot (like I had planned before, but
		had removed for some reason).
		Adding a quick-and-dirty fallback to legacy coprocessor 1
		code (i.e. skipping dyntrans implementation for now).
		NetBSD/hpcmips and NetBSD/pmax (when running on an emulated
		R4400) can now be installed and run. :-)  (Many bugs left
		to fix, though.)
		Adding more MIPS dyntrans instructions: madd[u], msub[u].
		Cleaning up the SPECIAL2 vs R5900/TX79/C790 "MMI" opcode
		maps somewhat (disassembly and dyntrans instruction decoding).
20060424	Adding an isa_revision field to mips_cpu_types.h, and making
		sure that SPECIAL3 opcodes cause Reserved Instruction
		exceptions on MIPS32/64 revisions lower than 2.
		Adding the SPARC 'ba', 'call', 'jmpl/retl', 'and', and 'xor'
		instructions.
20060425	Removing the -m command line option ("run at most x 
		instructions") and -T ("single_step_on_bad_addr"), because
		they never worked correctly with dyntrans anyway.
		Freshening up the man page.
20060428	Adding more MIPS dyntrans instructions: bltzal[l], idle.
		Enabling MIPS dyntrans compare interrupts.
20060429	FINALLY found the weird dyntrans bug, causing NetBSD etc. to
		behave strangely: some floating point code (conditional
		coprocessor branches) could not be reused from the old
		non-dyntrans code. The "quick-and-dirty fallback" only appeared
		to work. Fixing by implementing bc1* for MIPS dyntrans.
		More MIPS instructions: [d]sub, sdc1, ldc1, dmtc1, dmfc1, cfc0.
		Freshening up MIPS floating point disassembly appearance.
20060430	Continuing on C790/R5900/TX79 disassembly; implementing 128-bit
		"por" and "pextlw".
20060504	Disabling -u (userland emulation) unless compiled as unstable
		development version.
		Beginning on freshening up the testmachine include files,
		to make it easier to reuse those files (placing them in
		src/include/testmachine/), and beginning on a set of "demos"
		or "tutorials" for the testmachine functionality.
		Minor updates to the MIPS GDB remote protocol stub.
		Refreshing doc/experiments.html and gdb_remote.html.
		Enabling Alpha emulation in the stable release configuration,
		even though no guest OSes for Alpha can run yet.
20060505	Adding a generic 'settings' object, which will contain
		references to settable variables (which will later be possible
		to access using the debugger).
20060506	Updating dev_disk and corresponding demo/documentation (and
		switching from SCSI to IDE disk types, so it actually works
		with current test machines :-).
20060510	Adding a -D_LARGEFILE_SOURCE hack for 64-bit Linux hosts,
		so that fseeko() doesn't give a warning.
		Updating the section about how dyntrans works (the "runnable
		IR") in doc/intro.html.
		Instruction updates (some x64=1 checks, some more R5900
		dyntrans stuff: better mul/mult separation from MIPS32/64,
		adding ei and di).
		Updating MIPS cpuregs.h to a newer one (from NetBSD).
		Adding more MIPS dyntrans instructions: deret, ehb.
20060514	Adding disassembly and beginning implementation of SPARC wr
		and wrpr instructions.
20060515	Adding a SUN SPARC machine mode, with dummy SS20 and Ultra1
		machines. Adding the 32-bit "rd psr" instruction.
20060517	Disassembly support for the general SPARC rd instruction.
		Partial implementation of the cmp (subcc) instruction.
		Some other minor updates (making sure that R5900 processors
		start up with the EIE bit enabled, otherwise Linux/playstation2
		receives no interrupts).
20060519	Minor MIPS updates/cleanups.
20060521	Moving the MeshCube machine into evbmips; this seems to work
		reasonably well with a snapshot of a NetBSD MeshCube kernel.
		Cleanup/fix of MIPS config0 register initialization.
20060529	Minor MIPS fixes, including a sign-extension fix to the
		unaligned load/store code, which makes NetBSD/pmax on R3000
		work better with dyntrans. (Ultrix and Linux/DECstation still
		don't work, though.)
20060530	Minor updates to the Alpha machine mode: adding an AlphaBook
		mode, an LCA bus (forwarding accesses to an ISA bus), etc.
20060531	Applying a bugfix for the MIPS dyntrans sc[d] instruction from
		Ondrej Palkovsky. (Many thanks.)
20060601	Minifix to allow ARM immediate msr instruction to not give
		an error for some valid values.
		More Alpha updates.
20060602	Some minor Alpha updates.
20060603	Adding the Alpha cmpbge instruction. NetBSD/alpha prints its
		first boot messages :-) on an emulated Alphabook 1.
20060612	Minor updates; adding a dev_ether.h include file for the
		testmachine ether device. Continuing the hunt for the dyntrans
		bug which makes Linux and Ultrix on DECstation behave
		strangely... FINALLY found it! It seems to be related to
		invalidation of the translation cache, on tlbw{r,i}. There
		also seems to be some remaining interrupt-related problems.
20060614	Correcting the implementation of ldc1/sdc1 for MIPS dyntrans
		(so that it uses 16 32-bit registers if the FR bit in the
		status register is not set).
20060616	REMOVING BINTRANS COMPLETELY!
		Removing the old MIPS interpretation mode.
		Removing the MFHILO_DELAY and instruction delay stuff, because
		they wouldn't work with dyntrans anyway.
20060617	Some documentation updates (adding "NetBSD-archive" to some
		URLs, and new Debian/DECstation installation screenshots).
		Removing the "tracenull" and "enable-caches" configure options.
		Improving MIPS dyntrans performance somewhat (only invalidate
		translations if necessary, on writes to the entryhi register,
		instead of doing it for all cop0 writes).
20060618	More cleanup after the removal of the old MIPS emulation.
		Trying to fix the MIPS dyntrans performance bugs/bottlenecks;
		only semi-successful so far (for R3000).
20060620	Minor update to allow clean compilation again on Tru64/Alpha.
20060622	MIPS cleanup and fixes (removing the pc_last stuff, which
		doesn't make sense with dyntrans anyway, and fixing a cross-
		page-delay-slot-with-exception case in end_of_page).
		Removing the old max_random_cycles_per_chunk stuff, and the
		concept of cycles vs instructions for MIPS emulation.
		FINALLY found and fixed the bug which caused NetBSD/pmax
		clocks to behave strangely (it was a load to the zero register,
		which was treated as a NOP; now it is treated as a load to a
		dummy scratch register).
20060623	Increasing the dyntrans chunk size back to
		N_SAFE_DYNTRANS_LIMIT, instead of N_SAFE_DYNTRANS_LIMIT/2.
		Preparing for a quick release, even though there are known
		bugs, and performance for non-R3000 MIPS emulation is very
		poor. :-/
		Reverting to half the dyntrans chunk size again, because
		NetBSD/cats seemed less stable with full size chunks. :(
		NetBSD/sgimips 3.0 can now run :-)  (With release 0.3.8, only
		NetBSD/sgimips 2.1 worked, not 3.0.)

==============  RELEASE 0.4.0  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26