/[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 20 - (show annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 56939 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26