/[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

Annotation of /trunk/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations)
Mon Oct 8 16:20:26 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 57734 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1298 2006/07/22 11:27:46 debug Exp $
20060626	Continuing on SPARC emulation (beginning on the 'save'
		instruction, register windows, etc).
20060629	Planning statistics gathering (new -s command line option),
		and renaming speed_tricks to allow_instruction_combinations.
20060630	Some minor manual page updates.
		Various cleanups.
		Implementing the -s command line option.
20060701	FINALLY found the bug which prevented Linux and Ultrix from
		running without the ugly hack in the R2000/R3000 cache isol
		code; it was the phystranslation hint array which was buggy.
		Removing the phystranslation hint code completely, for now.
20060702	Minor dyntrans cleanups; invalidation of physpages now only
		invalidate those parts of a page that have actually been
		translated. (32 parts per page.)
		Some MIPS non-R3000 speed fixes.
		Experimenting with MIPS instruction combination for some
		addiu+bne+sw loops, and sw+sw+sw.
		Adding support (again) for larger-than-4KB pages in MIPS tlbw*.
		Continuing on SPARC emulation: adding load/store instructions.
20060704	Fixing a virtual vs physical page shift bug in the new tlbw*
		implementation. Problem noticed by Jakub Jermar. (Many thanks.)
		Moving rfe and eret to cpu_mips_instr.c, since that is the
		only place that uses them nowadays.
20060705	Removing the BSD license from the "testmachine" include files,
		placing them in the public domain instead; this enables the
		testmachine stuff to be used from projects which are
		incompatible with the BSD license for some reason.
20060707	Adding instruction combinations for the R2000/R3000 L1
		I-cache invalidation code used by NetBSD/pmax 3.0, lui+addiu,
		various branches followed by addiu or nop, and jr ra followed
		by addiu. The time it takes to perform a full NetBSD/pmax R3000
		install on the laptop has dropped from 573 seconds to 539. :-)
20060708	Adding a framebuffer controller device (dev_fbctrl), which so
		far can be used to change the fb resolution during runtime, but
		in the future will also be useful for accelerated block fill/
		copy, and possibly also simplified character output.
		Adding an instruction combination for NetBSD/pmax' strlen.
20060709	Minor fixes: reading raw files in src/file.c wasn't memblock
		aligned, removing buggy multi_sw MIPS instruction combination,
		etc.
20060711	Adding a machine_qemu.c, which contains a "qemu_mips" machine.
		(It mimics QEMU's MIPS machine mode, so that a test kernel
		made for QEMU_MIPS also can run in GXemul... at least to some
		extent.)  Adding a short section about how to run this mode to
		doc/guestoses.html.
20060714	Misc. minor code cleanups.
20060715	Applying a patch which adds getchar() to promemul/yamon.c
		(from Oleksandr Tymoshenko).
		Adding yamon.h from NetBSD, and rewriting yamon.c to use it
		(instead of ugly hardcoded numbers) + some cleanup.
20060716	Found and fixed the bug which broke single-stepping of 64-bit
		programs between 0.4.0 and 0.4.0.1 (caused by too quick
		refactoring and no testing). Hopefully this fix will not
		break too many other things.
20060718	Continuing on the 8253 PIT; it now works with Linux/QEMU_MIPS.
		Re-adding the sw+sw+sw instr comb (the problem was that I had
		ignored endian issues); however, it doesn't seem to give any
		big performance gain.
20060720	Adding a dummy Transputer mode (T414, T800 etc) skeleton (only
		the 'j' and 'ldc' instructions are implemented so far). :-}
20060721	Adding gtreg.h from NetBSD, updating dev_gt.c to use it, plus
		misc. other updates to get Linux 2.6 for evbmips/malta working
		(thanks to Alec Voropay for the details).
		FINALLY found and fixed the bug which made tlbw* for non-R3000
		buggy; it was a reference count problem in the dyntrans core.
20060722	Testing stuff; things seem stable enough for a new release.

==============  RELEASE 0.4.1  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26