/[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 22 - (hide annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 57702 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26