/[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 14 - (hide annotations)
Mon Oct 8 16:18:51 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 56559 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.982 2005/10/07 22:45:32 debug Exp $
20050816	Some success in decoding the way the SGI O2 PROM draws graphics
		during bootup; lines/rectangles and bitmaps work, enough to
		show the bootlogo etc. :-)
		Adding more PPC instructions, and (dummy) BAT registers.
20050817	Updating the pckbc to support scancode type 3 keyboards
		(required in order to interact with the SGI O2 PROM).
		Adding more PPC instructions.
20050818	Adding more ARM instructions; general register forms.
		Importing armreg.h from NetBSD (ARM cpu ids). Adding a (dummy)
		CATS machine mode (using SA110 as the default CPU).
		Continuing on general dyntrans related stuff.
20050819	Register forms for ARM load/stores. Gaah! The Compaq C Compiler
		bug is triggered for ARM loads as well, not just PPC :-(
		Adding full support for ARM PC-relative load/stores, and load/
		stores where the PC register is the destination register.
		Adding support for ARM a.out binaries.
20050820	Continuing to add more ARM instructions, and correcting some
		bugs. Continuing on CATS emulation.
		More work on the PPC stuff.
20050821	Minor PPC and ARM updates. Adding more machine types.
20050822	All ARM "data processing instructions" are now generated
		automatically.
20050824	Beginning the work on the ARM system control coprocessor.
		Adding support for ARM halfword load/stores, and signed loads.
20050825	Fixing an important bug related to the ARM condition codes.
		OpenBSD/zaurus and NetBSD/netwinder now print some boot
		messages. :)
		Adding a dummy SH (Hitachi SuperH) cpu family.
		Beginning to add some ARM virtual address translation.
		MIPS bugfixes: unaligned PC now cause an ADEL exception (at
		least for non-bintrans execution), and ADEL/ADES (not
		TLBL/TLBS) are used if userland tries to access kernel space.
		(Thanks to Joshua Wise for making me aware of these bugs.)
20050827	More work on the ARM emulation, and various other updates.
20050828	More ARM updates.
		Finally taking the time to work on translation invalidation
		(i.e. invalidating translated code mappings when memory is
		written to). Hopefully this doesn't break anything.
20050829	Moving CPU related files from src/ to a new subdir, src/cpus/.
		Moving PROM emulation stuff from src/ to src/promemul/.
		Better debug instruction trace for ARM loads and stores.
20050830	Various ARM updates (correcting CMP flag calculation, etc).
20050831	PPC instruction updates. (Flag fixes, etc.)
20050901	Various minor PPC and ARM instruction emulation updates.
		Minor OpenFirmware emulation updates.
20050903	Adding support for adding arbitrary ARM coprocessors (with
		the i80321 I/O coprocessor as a first test).
		Various other ARM and PPC updates.
20050904	Adding some SHcompact disassembly routines.
20050907	(Re)adding a dummy HPPA CPU module, and a dummy i960 module.
20050908	Began hacking on some Apple Partition Table support.
20050909	Adding support for loading Mach-O (Darwin PPC) binaries.
20050910	Fixing an ARM bug (Carry flag was incorrectly updated for some
		data processing instructions); OpenBSD/cats and NetBSD/
		netwinder get quite a bit further now.
		Applying a patch to dev_wdc, and a one-liner to dev_pcic, to
		make them work better when emulating new versions of OpenBSD.
		(Thanks to Alexander Yurchenko for the patches.)
		Also doing some other minor updates to dev_wdc. (Some cleanup,
		and finally converting to devinit, etc.)
20050912	IRIX doesn't have u_int64_t by default (noticed by Andreas
		<avr@gnulinux.nl>); configure updated to reflect this.
		Working on ARM register bank switching, CPSR vs SPSR issues,
		and beginning the work on interrupt/exception support.
20050913	Various minor ARM updates (speeding up load/store multiple,
		and fixing a ROR bug in R(); NetBSD/cats now boots as far as
		OpenBSD/cats).
20050917	Adding a dummy Atmel AVR (8-bit) cpu family skeleton.
20050918	Various minor updates.
20050919	Symbols are now loaded from Mach-O executables.
		Continuing the work on adding ARM exception support.
20050920	More work on ARM stuff: OpenBSD/cats and NetBSD/cats reach
		userland! :-)
20050921	Some more progress on ARM interrupt specifics.
20050923	Fixing linesize for VR4121 (patch by Yurchenko). Also fixing
		linesizes/cachesizes for some other VR4xxx.
		Adding a dummy Acer Labs M1543 PCI-ISA bridge (for CATS) and a
		dummy Symphony Labs 83C553 bridge (for Netwinder), usable by 
		dev_footbridge.
20050924	Some PPC progress.
20050925	More PPC progress.
20050926	PPC progress (fixing some bugs etc); Darwin's kernel gets
		slightly further than before.
20050928	Various updates: footbridge/ISA/pciide stuff, and finally
		fixing the VGA text scroll-by-changing-the-base-offset bug.
20050930	Adding a dummy S3 ViRGE pci card for CATS emulation, which
		both NetBSD and OpenBSD detects as VGA.
		Continuing on Footbridge (timers, ISA interrupt stuff).
20051001	Continuing... there are still bugs, probably interrupt-
		related.
20051002	More work on the Footbridge (interrupt stuff).
20051003	Various minor updates. (Trying to find the bug(s).)
20051004	Continuing on the ARM stuff.
20051005	More ARM-related fixes.
20051007	FINALLY! Found and fixed 2 ARM bugs: 1 memory related, and the
		other was because of an error in the ARM manual (load multiple
		with the S-bit set should _NOT_ load usermode registers, as the
		manual says, but it should load saved registers, which may or
		may not happen to be usermode registers).
		NetBSD/cats and OpenBSD/cats seem to install fine now :-)
		except for a minor bug at the end of the OpenBSD/cats install.
		Updating the documentation, preparing for the next release.
20051008	Continuing with release testing and cleanup.

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

  ViewVC Help
Powered by ViewVC 1.1.26