/[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 4 - (hide annotations)
Mon Oct 8 16:18:00 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 46138 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.3.2  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26