/[gxemul]/upstream/0.3.7/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 /upstream/0.3.7/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21 - (hide annotations)
Mon Oct 8 16:19:28 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 56939 byte(s)
0.3.7
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 20 * $Id: file.c,v 1.119 2005/11/19 21:00:59 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 dpavlin 20 case ARCH_NEWMIPS:
1396 dpavlin 2 switch (emachine) {
1397     case EM_MIPS:
1398     case EM_MIPS_RS3_LE:
1399     ok = 1;
1400     }
1401     break;
1402     case ARCH_PPC:
1403     switch (emachine) {
1404     case EM_PPC:
1405     case EM_PPC64:
1406     ok = 1;
1407     }
1408     break;
1409 dpavlin 14 case ARCH_SH:
1410     switch (emachine) {
1411     case EM_SH:
1412     ok = 1;
1413     }
1414     break;
1415 dpavlin 2 case ARCH_SPARC:
1416     switch (emachine) {
1417     case EM_SPARC:
1418     case EM_SPARCV9:
1419     ok = 1;
1420     }
1421     break;
1422 dpavlin 4 case ARCH_X86:
1423 dpavlin 2 switch (emachine) {
1424 dpavlin 4 case EM_386:
1425     case EM_486:
1426 dpavlin 6 *tocp = 1;
1427 dpavlin 2 ok = 1;
1428 dpavlin 4 break;
1429     case EM_AMD64:
1430 dpavlin 6 *tocp = 2;
1431 dpavlin 2 ok = 1;
1432 dpavlin 4 break;
1433 dpavlin 2 }
1434     break;
1435     default:
1436     fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
1437     }
1438     if (!ok) {
1439     fprintf(stderr, "%s: this is a ", filename);
1440     if (emachine >= 0 && emachine < N_ELF_MACHINE_TYPES)
1441     fprintf(stderr, elf_machine_type[emachine]);
1442     else
1443     fprintf(stderr, "machine type '%i'", emachine);
1444     fprintf(stderr, " ELF binary!\n");
1445     exit(1);
1446     }
1447    
1448     s = "entry point";
1449     if (elf64 && arch == ARCH_PPC)
1450     s = "function descriptor at";
1451    
1452     debug("ELF%i %s, %s 0x", elf64? 64 : 32,
1453     encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
1454    
1455     if (elf64)
1456     debug("%016llx\n", (long long)eentry);
1457     else
1458     debug("%08x\n", (int)eentry);
1459    
1460     /*
1461     * MIPS16 encoding?
1462     *
1463     * TODO: Find out what e_flag actually contains.
1464     * TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!
1465     */
1466 dpavlin 20 if ((arch == ARCH_MIPS || arch == ARCH_NEWMIPS)
1467     && ((eflags >> 24) & 0xff) == 0x24) {
1468 dpavlin 2 debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);
1469     #ifdef ENABLE_MIPS16
1470     m->cpus[0]->cd.mips.mips16 = 1;
1471     #else
1472     fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1473     "(or use the --mips16 configure option)\n");
1474     exit(1);
1475     #endif
1476 dpavlin 20 } else if ((arch == ARCH_MIPS || arch == ARCH_NEWMIPS)
1477     && (eentry & 0x3)) {
1478 dpavlin 2 debug("MIPS16 encoding (eentry not 32-bit aligned)\n");
1479     #ifdef ENABLE_MIPS16
1480     m->cpus[0]->cd.mips.mips16 = 1;
1481     #else
1482     fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1483     "(or use the --mips16 configure option)\n");
1484     exit(1);
1485     #endif
1486     }
1487    
1488 dpavlin 14 /*
1489     * SH64: 32-bit instruction encoding? TODO
1490     */
1491     if (arch == ARCH_SH && (eentry & 1)) {
1492     debug("SH64: 32-bit instruction encoding\n");
1493     m->cpus[0]->cd.sh.compact = 0;
1494     m->cpus[0]->cd.sh.bits = 64;
1495     }
1496    
1497 dpavlin 2 /* Read the program headers: */
1498    
1499     for (i=0; i<ephnum; i++) {
1500     int p_type;
1501     uint64_t p_offset;
1502     uint64_t p_vaddr;
1503     uint64_t p_paddr;
1504     uint64_t p_filesz;
1505     uint64_t p_memsz;
1506     int p_flags;
1507     int p_align;
1508    
1509     fseek(f, ephoff + i * ephentsize, SEEK_SET);
1510    
1511     if (elf64) {
1512     fread(&phdr64, 1, sizeof(Elf64_Phdr), f);
1513     unencode(p_type, &phdr64.p_type, Elf64_Half);
1514     unencode(p_flags, &phdr64.p_flags, Elf64_Half);
1515     unencode(p_offset, &phdr64.p_offset, Elf64_Off);
1516     unencode(p_vaddr, &phdr64.p_vaddr, Elf64_Addr);
1517     unencode(p_paddr, &phdr64.p_paddr, Elf64_Addr);
1518     unencode(p_filesz, &phdr64.p_filesz, Elf64_Xword);
1519     unencode(p_memsz, &phdr64.p_memsz, Elf64_Xword);
1520     unencode(p_align, &phdr64.p_align, Elf64_Xword);
1521     } else {
1522     fread(&phdr32, 1, sizeof(Elf32_Phdr), f);
1523     unencode(p_type, &phdr32.p_type, Elf32_Word);
1524     unencode(p_offset, &phdr32.p_offset, Elf32_Off);
1525     unencode(p_vaddr, &phdr32.p_vaddr, Elf32_Addr);
1526     unencode(p_paddr, &phdr32.p_paddr, Elf32_Addr);
1527     unencode(p_filesz, &phdr32.p_filesz, Elf32_Word);
1528     unencode(p_memsz, &phdr32.p_memsz, Elf32_Word);
1529     unencode(p_flags, &phdr32.p_flags, Elf32_Word);
1530     unencode(p_align, &phdr32.p_align, Elf32_Word);
1531     }
1532    
1533 dpavlin 20 /*
1534     * Hack for loading Linux/PPC kernels, linked to high
1535     * addresses, at low addresses.
1536     */
1537     if (arch == ARCH_PPC) {
1538     if (elf64) {
1539     p_vaddr &= 0x0fffffffffffffffULL;
1540     p_paddr &= 0x0fffffffffffffffULL;
1541     } else {
1542     p_vaddr &= 0x0fffffff;
1543     p_paddr &= 0x0fffffff;
1544     }
1545     }
1546    
1547 dpavlin 2 if (p_memsz != 0 && (p_type == PT_LOAD ||
1548     (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1549     debug("chunk %i (", i);
1550     if (p_type == PT_LOAD)
1551     debug("load");
1552     else
1553     debug("0x%08x", (int)p_type);
1554    
1555     debug(") @ 0x%llx, vaddr 0x", (long long)p_offset);
1556    
1557     if (elf64)
1558     debug("%016llx", (long long)p_vaddr);
1559     else
1560     debug("%08x", (int)p_vaddr);
1561    
1562     debug(" len=0x%llx\n", (long long)p_memsz);
1563    
1564 dpavlin 10 if (p_vaddr != p_paddr)
1565     fatal("WARNING! vaddr (0x%llx) and paddr "
1566     "(0x%llx) differ; using vaddr\n",
1567     (long long)p_vaddr, (long long)p_paddr);
1568 dpavlin 2
1569     if (p_memsz < p_filesz) {
1570     fprintf(stderr, "%s: memsz < filesz. TODO: how"
1571     " to handle this? memsz=%016llx filesz="
1572     "%016llx\n", filename, (long long)p_memsz,
1573     (long long)p_filesz);
1574     exit(1);
1575     }
1576    
1577     fseek(f, p_offset, SEEK_SET);
1578     align_len = 1;
1579     if ((p_vaddr & 0xf)==0) align_len = 0x10;
1580     if ((p_vaddr & 0x3f)==0) align_len = 0x40;
1581     if ((p_vaddr & 0xff)==0) align_len = 0x100;
1582     if ((p_vaddr & 0xfff)==0) align_len = 0x1000;
1583     if ((p_vaddr & 0x3fff)==0) align_len = 0x4000;
1584     if ((p_vaddr & 0xffff)==0) align_len = 0x10000;
1585     ofs = 0; len = chunk_len = align_len;
1586     while (ofs < (int64_t)p_filesz && len==chunk_len) {
1587     unsigned char *ch = malloc(chunk_len);
1588     int i = 0;
1589    
1590     /* Switch to larger size, if possible: */
1591     if (align_len < 0x10000 &&
1592     ((p_vaddr + ofs) & 0xffff)==0) {
1593     align_len = 0x10000;
1594     len = chunk_len = align_len;
1595     free(ch);
1596     ch = malloc(chunk_len);
1597     } else if (align_len < 0x1000 &&
1598     ((p_vaddr + ofs) & 0xfff)==0) {
1599     align_len = 0x1000;
1600     len = chunk_len = align_len;
1601     free(ch);
1602     ch = malloc(chunk_len);
1603     }
1604    
1605     if (ch == NULL) {
1606     fprintf(stderr, "out of memory\n");
1607     exit(1);
1608     }
1609    
1610     len = fread(&ch[0], 1, chunk_len, f);
1611     if (ofs + len > (int64_t)p_filesz)
1612     len = p_filesz - ofs;
1613    
1614     while (i < len) {
1615     size_t len_to_copy;
1616     len_to_copy = (i + align_len) <= len?
1617     align_len : len - i;
1618     m->cpus[0]->memory_rw(m->cpus[0], mem,
1619     p_vaddr + ofs, &ch[i], len_to_copy,
1620     MEM_WRITE, NO_EXCEPTIONS);
1621     ofs += align_len;
1622     i += align_len;
1623     }
1624    
1625     free(ch);
1626     }
1627     }
1628     }
1629    
1630 dpavlin 12 /*
1631     * Read the section headers to find the address of the _gp
1632     * symbol (for MIPS):
1633     */
1634 dpavlin 2
1635     for (i=0; i<eshnum; i++) {
1636     int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
1637     uint64_t sh_addr, sh_size, sh_addralign;
1638     off_t sh_offset;
1639     int n_entries; /* for reading the symbol / string tables */
1640    
1641     /* debug("section header %i at %016llx\n", i,
1642     (long long) eshoff+i*eshentsize); */
1643    
1644     fseek(f, eshoff + i * eshentsize, SEEK_SET);
1645    
1646     if (elf64) {
1647     len = fread(&shdr64, 1, sizeof(Elf64_Shdr), f);
1648     if (len != sizeof(Elf64_Shdr)) {
1649     fprintf(stderr, "couldn't read header\n");
1650     exit(1);
1651     }
1652     unencode(sh_name, &shdr64.sh_name, Elf64_Half);
1653     unencode(sh_type, &shdr64.sh_type, Elf64_Half);
1654     unencode(sh_flags, &shdr64.sh_flags, Elf64_Xword);
1655     unencode(sh_addr, &shdr64.sh_addr, Elf64_Addr);
1656     unencode(sh_offset, &shdr64.sh_offset, Elf64_Off);
1657     unencode(sh_size, &shdr64.sh_size, Elf64_Xword);
1658     unencode(sh_link, &shdr64.sh_link, Elf64_Half);
1659     unencode(sh_info, &shdr64.sh_info, Elf64_Half);
1660     unencode(sh_addralign, &shdr64.sh_addralign,
1661     Elf64_Xword);
1662     unencode(sh_entsize, &shdr64.sh_entsize, Elf64_Xword);
1663     } else {
1664     len = fread(&shdr32, 1, sizeof(Elf32_Shdr), f);
1665     if (len != sizeof(Elf32_Shdr)) {
1666     fprintf(stderr, "couldn't read header\n");
1667     exit(1);
1668     }
1669     unencode(sh_name, &shdr32.sh_name, Elf32_Word);
1670     unencode(sh_type, &shdr32.sh_type, Elf32_Word);
1671     unencode(sh_flags, &shdr32.sh_flags, Elf32_Word);
1672     unencode(sh_addr, &shdr32.sh_addr, Elf32_Addr);
1673     unencode(sh_offset, &shdr32.sh_offset, Elf32_Off);
1674     unencode(sh_size, &shdr32.sh_size, Elf32_Word);
1675     unencode(sh_link, &shdr32.sh_link, Elf32_Word);
1676     unencode(sh_info, &shdr32.sh_info, Elf32_Word);
1677     unencode(sh_addralign, &shdr32.sh_addralign,Elf32_Word);
1678     unencode(sh_entsize, &shdr32.sh_entsize, Elf32_Word);
1679     }
1680    
1681     /* debug("sh_name=%04lx, sh_type=%08lx, sh_flags=%08lx"
1682     " sh_size=%06lx sh_entsize=%03lx\n",
1683     (long)sh_name, (long)sh_type, (long)sh_flags,
1684     (long)sh_size, (long)sh_entsize); */
1685    
1686     /* Perhaps it is bad to reuse sh_entsize like this? TODO */
1687     if (elf64)
1688     sh_entsize = sizeof(Elf64_Sym);
1689     else
1690     sh_entsize = sizeof(Elf32_Sym);
1691    
1692     if (sh_type == SHT_SYMTAB) {
1693     size_t len;
1694     n_entries = sh_size / sh_entsize;
1695    
1696     fseek(f, sh_offset, SEEK_SET);
1697    
1698     if (elf64) {
1699     if (symbols_sym64 != NULL)
1700     free(symbols_sym64);
1701     symbols_sym64 = malloc(sh_size);
1702     if (symbols_sym64 == NULL) {
1703     fprintf(stderr, "out of memory\n");
1704     exit(1);
1705     }
1706    
1707     len = fread(symbols_sym64, 1, sh_entsize *
1708     n_entries, f);
1709     } else {
1710     if (symbols_sym32 != NULL)
1711     free(symbols_sym32);
1712     symbols_sym32 = malloc(sh_size);
1713     if (symbols_sym32 == NULL) {
1714     fprintf(stderr, "out of memory\n");
1715     exit(1);
1716     }
1717    
1718     len = fread(symbols_sym32, 1,
1719     sh_entsize * n_entries, f);
1720     }
1721    
1722     if (len != sh_size) {
1723     fprintf(stderr, "could not read symbols from "
1724     "%s\n", filename);
1725     exit(1);
1726     }
1727    
1728     debug("%i symbol entries at 0x%llx\n",
1729     (int)n_entries, (long long)sh_offset);
1730    
1731     n_symbols = n_entries;
1732     }
1733    
1734     /*
1735     * TODO: This is incorrect, there may be several strtab
1736     * sections.
1737     *
1738     * For now, the simple/stupid guess that the largest string
1739     * table is the one to use seems to be good enough.
1740     */
1741    
1742     if (sh_type == SHT_STRTAB && sh_size > symbol_length) {
1743     size_t len;
1744    
1745     if (symbol_strings != NULL)
1746     free(symbol_strings);
1747    
1748     symbol_strings = malloc(sh_size + 1);
1749     if (symbol_strings == NULL) {
1750     fprintf(stderr, "out of memory\n");
1751     exit(1);
1752     }
1753    
1754     fseek(f, sh_offset, SEEK_SET);
1755     len = fread(symbol_strings, 1, sh_size, f);
1756     if (len != sh_size) {
1757     fprintf(stderr, "could not read symbols from "
1758     "%s\n", filename);
1759     exit(1);
1760     }
1761    
1762     debug("%i bytes of symbol strings at 0x%llx\n",
1763     (int)sh_size, (long long)sh_offset);
1764    
1765     symbol_strings[sh_size] = '\0';
1766     symbol_length = sh_size;
1767     }
1768     }
1769    
1770     fclose(f);
1771    
1772     /* Decode symbols: */
1773     if (symbol_strings != NULL) {
1774     for (i=0; i<n_symbols; i++) {
1775     uint64_t st_name, addr, size;
1776     int st_info;
1777    
1778     if (elf64) {
1779     sym64 = symbols_sym64[i];
1780     unencode(st_name, &sym64.st_name, Elf64_Half);
1781     unencode(st_info, &sym64.st_info, Elf_Byte);
1782     unencode(addr, &sym64.st_value, Elf64_Addr);
1783     unencode(size, &sym64.st_size, Elf64_Xword);
1784     } else {
1785     sym32 = symbols_sym32[i];
1786     unencode(st_name, &sym32.st_name, Elf32_Word);
1787 dpavlin 20 unencode(st_info, &sym32.st_info, Elf_Byte);
1788 dpavlin 2 unencode(addr, &sym32.st_value, Elf32_Word);
1789     unencode(size, &sym32.st_size, Elf32_Word);
1790     }
1791    
1792 dpavlin 12 /* debug("symbol info=0x%02x addr=0x%016llx"
1793     " (%i) '%s'\n", st_info, (long long)addr,
1794     st_name, symbol_strings + st_name); */
1795    
1796 dpavlin 2 if (size == 0)
1797     size ++;
1798    
1799 dpavlin 6 if (addr != 0) /* && ((st_info >> 4) & 0xf)
1800     >= STB_GLOBAL) */ {
1801 dpavlin 2 /* debug("symbol info=0x%02x addr=0x%016llx"
1802     " '%s'\n", st_info, (long long)addr,
1803     symbol_strings + st_name); */
1804     add_symbol_name(&m->symbol_context,
1805 dpavlin 12 addr, size, symbol_strings + st_name,
1806     0, -1);
1807 dpavlin 2 }
1808    
1809     if (strcmp(symbol_strings + st_name, "_gp") == 0) {
1810     debug("found _gp address: 0x");
1811     if (elf64)
1812     debug("%016llx\n", (long long)addr);
1813     else
1814     debug("%08x\n", (int)addr);
1815     *gpp = addr;
1816     }
1817     }
1818     }
1819    
1820     *entrypointp = eentry;
1821    
1822     if (encoding == ELFDATA2LSB)
1823     *byte_order = EMUL_LITTLE_ENDIAN;
1824     else
1825     *byte_order = EMUL_BIG_ENDIAN;
1826    
1827     if (elf64 && arch == ARCH_PPC) {
1828     /*
1829     * Special case for 64-bit PPC ELFs:
1830     *
1831     * The ELF starting symbol points to a ".opd" section
1832     * which contains a function descriptor:
1833     *
1834     * uint64_t start;
1835     * uint64_t toc_base;
1836     * uint64_t something_else; (?)
1837     */
1838     int res;
1839     unsigned char b[sizeof(uint64_t)];
1840     uint64_t toc_base;
1841    
1842     debug("PPC64: ");
1843    
1844     res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry, b,
1845     sizeof(b), MEM_READ, NO_EXCEPTIONS);
1846     if (!res)
1847     debug(" [WARNING: could not read memory?] ");
1848    
1849     /* PPC are always big-endian: */
1850     *entrypointp = ((uint64_t)b[0] << 56) +
1851     ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1852     ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1853     ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1854     (uint64_t)b[7];
1855    
1856     res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry + 8,
1857     b, sizeof(b), MEM_READ, NO_EXCEPTIONS);
1858     if (!res)
1859     fatal(" [WARNING: could not read memory?] ");
1860    
1861     toc_base = ((uint64_t)b[0] << 56) +
1862     ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1863     ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1864     ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1865     (uint64_t)b[7];
1866    
1867     debug("entrypoint 0x%016llx, toc_base 0x%016llx\n",
1868     (long long)*entrypointp, (long long)toc_base);
1869     if (tocp != NULL)
1870     *tocp = toc_base;
1871     }
1872    
1873     n_executables_loaded ++;
1874     }
1875    
1876    
1877     /*
1878     * file_n_executables_loaded():
1879     *
1880     * Returns the number of executable files loaded into emulated memory.
1881     */
1882     int file_n_executables_loaded(void)
1883     {
1884     return n_executables_loaded;
1885     }
1886    
1887    
1888     /*
1889     * file_load():
1890     *
1891     * Sense the file format of a file (ELF, a.out, ecoff), and call the
1892     * right file_load_XXX() function. If the file isn't of a recognized
1893     * binary format, assume that it contains symbol definitions.
1894     *
1895     * If the filename doesn't exist, try to treat the name as
1896     * "address:filename" and load the file as a raw binary.
1897     */
1898     void file_load(struct machine *machine, struct memory *mem,
1899     char *filename, uint64_t *entrypointp,
1900     int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)
1901     {
1902     int iadd = 4;
1903     FILE *f;
1904     unsigned char buf[12];
1905 dpavlin 6 unsigned char buf2[2];
1906     size_t len, len2, i;
1907 dpavlin 2 off_t size;
1908    
1909     if (byte_orderp == NULL) {
1910     fprintf(stderr, "file_load(): byte_order == NULL\n");
1911     exit(1);
1912     }
1913    
1914     if (arch == ARCH_NOARCH) {
1915     fprintf(stderr, "file_load(): FATAL ERROR: no arch?\n");
1916     exit(1);
1917     }
1918    
1919     if (mem == NULL || filename == NULL) {
1920     fprintf(stderr, "file_load(): mem or filename is NULL\n");
1921     exit(1);
1922     }
1923    
1924     /* Skip configuration files: */
1925     if (filename[0] == '@')
1926     return;
1927    
1928     debug("loading %s:\n", filename);
1929     debug_indentation(iadd);
1930    
1931     f = fopen(filename, "r");
1932     if (f == NULL) {
1933     file_load_raw(machine, mem, filename, entrypointp);
1934     goto ret;
1935     }
1936    
1937     fseek(f, 0, SEEK_END);
1938 dpavlin 10 size = ftello(f);
1939 dpavlin 2 fseek(f, 0, SEEK_SET);
1940    
1941     memset(buf, 0, sizeof(buf));
1942     len = fread(buf, 1, sizeof(buf), f);
1943 dpavlin 6 fseek(f, 510, SEEK_SET);
1944     len2 = fread(buf2, 1, sizeof(buf2), f);
1945 dpavlin 2 fclose(f);
1946    
1947     if (len < (signed int)sizeof(buf)) {
1948     fprintf(stderr, "\nThis file is too small to contain "
1949     "anything useful\n");
1950     exit(1);
1951     }
1952    
1953     /* Is it an ELF? */
1954     if (buf[0] == 0x7f && buf[1]=='E' && buf[2]=='L' && buf[3]=='F') {
1955     file_load_elf(machine, mem, filename,
1956     entrypointp, arch, gpp, byte_orderp, tocp);
1957     goto ret;
1958     }
1959    
1960 dpavlin 6 /* Is it an a.out? */
1961 dpavlin 2 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1962 dpavlin 6 /* MIPS a.out */
1963 dpavlin 2 file_load_aout(machine, mem, filename, 0,
1964     entrypointp, arch, byte_orderp);
1965     goto ret;
1966     }
1967 dpavlin 12 if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
1968     /* M68K a.out */
1969     file_load_aout(machine, mem, filename,
1970     AOUT_FLAG_VADDR_ZERO_HACK /* for OpenBSD/mac68k */,
1971     entrypointp, arch, byte_orderp);
1972     goto ret;
1973     }
1974 dpavlin 14 if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
1975     /* ARM a.out */
1976     file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1977     entrypointp, arch, byte_orderp);
1978     goto ret;
1979     }
1980 dpavlin 6 if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
1981     /* i386 a.out (old OpenBSD and NetBSD etc) */
1982     file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1983     entrypointp, arch, byte_orderp);
1984     goto ret;
1985     }
1986 dpavlin 2 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
1987 dpavlin 6 /* DEC OSF1 on MIPS: */
1988     file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
1989 dpavlin 2 entrypointp, arch, byte_orderp);
1990     goto ret;
1991     }
1992    
1993     /*
1994 dpavlin 14 * Is it a Mach-O file?
1995     */
1996     if (buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa &&
1997     (buf[3] == 0xce || buf[3] == 0xcf)) {
1998     file_load_macho(machine, mem, filename, entrypointp,
1999     arch, byte_orderp, buf[3] == 0xcf, 0);
2000     goto ret;
2001     }
2002     if ((buf[0] == 0xce || buf[0] == 0xcf) && buf[1] == 0xfa &&
2003     buf[2] == 0xed && buf[3] == 0xfe) {
2004     file_load_macho(machine, mem, filename, entrypointp,
2005     arch, byte_orderp, buf[0] == 0xcf, 1);
2006     goto ret;
2007     }
2008    
2009     /*
2010 dpavlin 2 * Is it an ecoff?
2011     *
2012     * TODO: What's the deal with the magic value's byte order? Sometimes
2013     * it seems to be reversed for BE when compared to LE, but not always?
2014     */
2015     if (buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB ||
2016     buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL ||
2017     buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB2 ||
2018     buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL2 ||
2019     buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB3 ||
2020     buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL3 ||
2021     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB ||
2022     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL ||
2023     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB2 ||
2024     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL2 ||
2025     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB3 ||
2026     buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL3) {
2027     file_load_ecoff(machine, mem, filename, entrypointp,
2028     arch, gpp, byte_orderp);
2029     goto ret;
2030     }
2031    
2032     /* Is it a Motorola SREC file? */
2033     if ((buf[0]=='S' && buf[1]>='0' && buf[1]<='9')) {
2034     file_load_srec(machine, mem, filename, entrypointp);
2035     goto ret;
2036     }
2037    
2038     /* gzipped files are not supported: */
2039     if (buf[0]==0x1f && buf[1]==0x8b) {
2040     fprintf(stderr, "\nYou need to gunzip the file before you"
2041     " try to use it.\n");
2042     exit(1);
2043     }
2044    
2045     if (size > 24000000) {
2046     fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
2047     (long long)size);
2048     fprintf(stderr, "Are you sure it is a kernel and not a disk "
2049 dpavlin 6 "image? (Use the -d option.)\n");
2050 dpavlin 2 exit(1);
2051     }
2052    
2053 dpavlin 4 if (size == 1474560)
2054     fprintf(stderr, "Hm... this file is the size of a 1.44 MB "
2055     "floppy image. Maybe you forgot the\n-d switch?\n");
2056    
2057 dpavlin 2 /*
2058     * Last resort: symbol definitions from nm (or nm -S):
2059     *
2060     * If the buf contains typical 'binary' characters, then print
2061     * an error message and quit instead of assuming that it is a
2062     * symbol file.
2063     */
2064     for (i=0; i<(signed)sizeof(buf); i++)
2065     if (buf[i] < 32 && buf[i] != '\t' &&
2066     buf[i] != '\n' && buf[i] != '\r' &&
2067     buf[i] != '\f') {
2068     fprintf(stderr, "\nThe file format of '%s' is "
2069     "unknown.\n\n ", filename);
2070     for (i=0; i<(signed)sizeof(buf); i++)
2071     fprintf(stderr, " %02x", buf[i]);
2072 dpavlin 6
2073     if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
2074     fprintf(stderr, "\n\nIt has a PC-style "
2075     "bootsector marker.");
2076    
2077 dpavlin 2 fprintf(stderr, "\n\nPossible explanations:\n\n"
2078     " o) If this is a disk image, you forgot '-d' "
2079     "on the command line.\n"
2080     " o) This is an unsupported binary format.\n\n");
2081     exit(1);
2082     }
2083    
2084     symbol_readfile(&machine->symbol_context, filename);
2085    
2086     ret:
2087     debug_indentation(-iadd);
2088     }
2089    

  ViewVC Help
Powered by ViewVC 1.1.26