/[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 12 - (show annotations)
Mon Oct 8 16:18:38 2007 UTC (12 years, 2 months ago) by dpavlin
File MIME type: text/plain
File size: 48299 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.905 2005/08/16 09:16:24 debug Exp $
20050628	Continuing the work on the ARM translation engine. end_of_page
		works. Experimenting with load/store translation caches
		(virtual -> physical -> host).
20050629	More ARM stuff (memory access translation cache, mostly). This
		might break a lot of stuff elsewhere, probably some MIPS-
		related translation things.
20050630	Many load/stores are now automatically generated and included
		into cpu_arm_instr.c; 1024 functions in total (!).
		Fixes based on feedback from Alec Voropay: only print 8 hex
		digits instead of 16 in some cases when emulating 32-bit
		machines; similar 8 vs 16 digit fix for breakpoint addresses;
		4Kc has 16 TLB entries, not 48; the MIPS config select1
		register is now printed with "reg ,0".
		Also changing many other occurances of 16 vs 8 digit output.
		Adding cache associativity fields to mips_cpu_types.h; updating
		some other cache fields; making the output of
		mips_cpu_dumpinfo() look nicer.
		Generalizing the bintrans stuff for device accesses to also
		work with the new translation system. (This might also break
		some MIPS things.)
		Adding multi-load/store instructions to the ARM disassembler
		and the translator, and some optimizations of various kinds.
20050701	Adding a simple dev_disk (it can read/write sectors from
		disk images).
20050712	Adding dev_ether (a simple ethernet send/receive device).
		Debugger command "ninstrs" for toggling show_nr_of_instructions
		during runtime.
		Removing the framebuffer logo.
20050713	Continuing on dev_ether.
		Adding a dummy cpu_alpha (again).
20050714	More work on cpu_alpha.
20050715	More work on cpu_alpha. Many instructions work, enough to run
		a simple framebuffer fill test (similar to the ARM test).
20050716	More Alpha stuff.
20050717	Minor updates (Alpha stuff).
20050718	Minor updates (Alpha stuff).
20050719	Generalizing some Alpha instructions.
20050720	More Alpha-related updates.
20050721	Continuing on cpu_alpha. Importing rpb.h from NetBSD/alpha.
20050722	Alpha-related updates: userland stuff (Hello World using
		write() compiled statically for FreeBSD/Alpha runs fine), and
		more instructions are now implemented.
20050723	Fixing ldq_u and stq_u.
		Adding more instructions (conditional moves, masks, extracts,
		shifts).
20050724	More FreeBSD/Alpha userland stuff, and adding some more
		instructions (inserts).
20050725	Continuing on the Alpha stuff. (Adding dummy ldt/stt.)
		Adding a -A command line option to turn off alignment checks
		in some cases (for translated code).
		Trying to remove the old bintrans code which updated the pc
		and nr_of_executed_instructions for every instruction.
20050726	Making another attempt att removing the pc/nr of instructions
		code. This time it worked, huge performance increase for
		artificial test code, but performance loss for real-world
		code :-( so I'm scrapping that code for now.
		Tiny performance increase on Alpha (by using ret instead of
		jmp, to play nice with the Alpha's branch prediction) for the
		old MIPS bintrans backend.
20050727	Various minor fixes and cleanups.
20050728	Switching from a 2-level virtual to host/physical translation
		system for ARM emulation, to a 1-level translation.
		Trying to switch from 2-level to 1-level for the MIPS bintrans
		system as well (Alpha only, so far), but there is at least one
		problem: caches and/or how they work with device mappings.
20050730	Doing the 2-level to 1-level conversion for the i386 backend.
		The cache/device bug is still there for R2K/3K :(
		Various other minor updates (Malta etc).
		The mc146818 clock now updates the UIP bit in a way which works
		better with Linux for at least sgimips and Malta emulation.
		Beginning the work on refactoring the dyntrans system.
20050731	Continuing the dyntrans refactoring.
		Fixing a small but serious host alignment bug in memory_rw.
		Adding support for big-endian load/stores to the i386 bintrans
		backend.
		Another minor i386 bintrans backend update: stores from the
		zero register are now one (or two) loads shorter.
		The slt and sltu instructions were incorrectly implemented for
		the i386 backend; only using them for 32-bit mode for now.
20050801	Continuing the dyntrans refactoring.
		Cleanup of the ns16550 serial controller (removing unnecessary
		code).
		Bugfix (memory corruption bug) in dev_gt, and a patch/hack from
		Alec Voropay for Linux/Malta.
20050802	More cleanup/refactoring of the dyntrans subsystem: adding
		phys_page pointers to the lookup tables, for quick jumps
		between translated pages.
		Better fix for the ns16550 device (but still no real FIFO
		functionality).
		Converting cpu_ppc to the new dyntrans system. This means that
		I will have to start from scratch with implementing each
		instruction, and figure out how to implement dual 64/32-bit
		modes etc.
		Removing the URISC CPU family, because it was useless.
20050803	When selecting a machine type, the main type can now be omitted
		if the subtype name is unique. (I.e. -E can be omitted.)
		Fixing a dyntrans/device update bug. (Writes to offset 0 of
		a device could sometimes go unnoticed.)
		Adding an experimental "instruction combination" hack for
		ARM for memset-like byte fill loops.
20050804	Minor progress on cpu_alpha and related things.
		Finally fixing the MIPS dmult/dmultu bugs.
		Fixing some minor TODOs.
20050805	Generalizing the 8259 PIC. It now also works with Cobalt
		and evbmips emulation, in addition to the x86 hack.
		Finally converting the ns16550 device to use devinit.
		Continuing the work on the dyntrans system. Thinking about
		how to add breakpoints.
20050806	More dyntrans updates. Breakpoints seem to work now.
20050807	Minor updates: cpu_alpha and related things; removing
		dev_malta (as it isn't used any more).
		Dyntrans: working on general "show trace tree" support.
		The trace tree stuff now works with both the old MIPS code and
		with newer dyntrans modes. :)
		Continuing on Alpha-related stuff (trying to get *BSD to boot
		a bit further, adding more instructions, etc).
20050808	Adding a dummy IA64 cpu family, and continuing the refactoring
		of the dyntrans system.
		Removing the regression test stuff, because it was more or
		less useless.
		Adding loadlinked/storeconditional type instructions to the
		Alpha emulation. (Needed for Linux/alpha. Not very well tested
		yet.)
20050809	The function call trace tree now prints a per-function nr of
		arguments. (Semi-meaningless, since that data isn't read yet
		from the ELFs; some hardcoded symbols such as memcpy() and
		strlen() work fine, though.)
		More dyntrans refactoring; taking out more of the things that
		are common to all cpu families.
20050810	Working on adding support for "dual mode" for PPC dyntrans
		(i.e. both 64-bit and 32-bit modes).
		(Re)adding some simple PPC instructions.
20050811	Adding a dummy M68K cpu family. The dyntrans system isn't ready
		for variable-length ISAs yet, so it's completely bogus so far.
		Re-adding more PPC instructions.
		Adding a hack to src/file.c which allows OpenBSD/mac68k a.out
		kernels to be loaded.
		Beginning to add PPC loads/stores. So far they only work in
		32-bit mode.
20050812	The configure file option "add_remote" now accepts symbolic
		host names, in addition to numeric IPv4 addresses.
		Re-adding more PPC instructions.
20050814	Continuing to port back more PPC instructions.
		Found and fixed the cache/device write-update bug for 32-bit
		MIPS bintrans. :-)
		Triggered a really weird and annoying bug in Compaq's C
		compiler; ccc sometimes outputs code which loads from an
		address _before_ checking whether the pointer was NULL or not.
		(I'm not sure how to handle this problem.)
20050815	Removing all of the old x86 instruction execution code; adding
		a new (dummy) dyntrans module for x86.
		Taking the first steps to extend the dyntrans system to support
		variable-length instructions.
		Slowly preparing for the next release.
20050816	Adding a dummy SPARC cpu module.
		Minor updates (documentation etc) for the release.

==============  RELEASE 0.3.5  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26